aboutsummaryrefslogtreecommitdiff
path: root/src/apt-watcher.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/apt-watcher.c')
-rw-r--r--src/apt-watcher.c506
1 files changed, 146 insertions, 360 deletions
diff --git a/src/apt-watcher.c b/src/apt-watcher.c
index 481029a..6e8a5c9 100644
--- a/src/apt-watcher.c
+++ b/src/apt-watcher.c
@@ -17,150 +17,113 @@ You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <gio/gio.h>
+// Conor - 6/2/2012
+// Please pull in packagekit's client lib
+// using apt-get install --no-install-recommends libpackagekit-glib2-dev
+// make sure you don't install package-kit
+#define I_KNOW_THE_PACKAGEKIT_GLIB2_API_IS_SUBJECT_TO_CHANGE
+
#include <glib/gi18n.h>
+#include <packagekit-glib2/packagekit.h>
#include "apt-watcher.h"
-#include "apt-transaction.h"
+#include "dbus-shared-names.h"
static guint watcher_id;
struct _AptWatcher
{
GObject parent_instance;
- guint reboot_query;
- GCancellable * proxy_cancel;
- GDBusProxy * proxy;
SessionDbus* session_dbus_interface;
DbusmenuMenuitem* apt_item;
AptState current_state;
- AptTransaction* current_transaction;
+ GCancellable * proxy_cancel;
+ GDBusProxy * proxy;
};
-
-static void
-apt_watcher_on_name_appeared (GDBusConnection *connection,
- const gchar *name,
- const gchar *name_owner,
- gpointer user_data);
-static void
-apt_watcher_on_name_vanished (GDBusConnection *connection,
- const gchar *name,
- gpointer user_data);
-static void fetch_proxy_cb (GObject * object,
- GAsyncResult * res,
- gpointer user_data);
-
-static void apt_watcher_upgrade_system_cb (GObject * obj,
- GAsyncResult * res,
- gpointer user_data);
-
-
-static void apt_watcher_show_apt_dialog (DbusmenuMenuitem* mi,
- guint timestamp,
- gpointer userdata);
-
-static void apt_watcher_signal_cb (GDBusProxy* proxy,
- gchar* sender_name,
- gchar* signal_name,
- GVariant* parameters,
- 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);
+
static void
-apt_watcher_init (AptWatcher *self)
+get_updates_complete (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
{
- self->current_state = UP_TO_DATE;
- self->proxy_cancel = g_cancellable_new();
- self->proxy = NULL;
- self->reboot_query = 0;
- self->current_transaction = NULL;
- g_timeout_add_seconds (60,
- apt_watcher_start_apt_interaction,
- self);
-}
+ g_return_if_fail (APT_IS_WATCHER (user_data));
+ AptWatcher* self = APT_WATCHER (user_data);
-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,
- "org.debian.apt",
- "/org/debian/apt",
- "org.debian.apt",
- self->proxy_cancel,
- fetch_proxy_cb,
- self);
- return FALSE;
-}
+ PkResults *results;
+ GError *error = NULL;
+ results = pk_client_generic_finish (PK_CLIENT(source_object), res, &error);
+
+ if (error != NULL){
+ g_warning ("Unable to query for updates - error - %s", error->message);
+ return;
+ }
-static void
-apt_watcher_finalize (GObject *object)
-{
- g_bus_unwatch_name (watcher_id);
- AptWatcher* self = APT_WATCHER (object);
-
- if (self->proxy != NULL)
- g_object_unref (self->proxy);
+ GPtrArray *packages;
+ packages = pk_results_get_package_array (results);
- G_OBJECT_CLASS (apt_watcher_parent_class)->finalize (object);
+ const gchar* disposition;
+ disposition = dbusmenu_menuitem_property_get (self->apt_item,
+ DBUSMENU_MENUITEM_PROP_DISPOSITION);
+ gboolean do_update;
+ do_update = g_strcmp0 (disposition, DBUSMENU_MENUITEM_DISPOSITION_ALERT) != 0;
+
+ if (packages->len > 0){
+ g_print ("Apparently we have updates available - change dbmitem %i", do_update);
+ if (do_update)
+ dbusmenu_menuitem_property_set (self->apt_item,
+ DBUSMENU_MENUITEM_PROP_LABEL,
+ _("Updates Available…"));
+ }
+ else{
+ g_print ("No updates available - change dbmitem - %i", do_update);
+ if (do_update)
+ dbusmenu_menuitem_property_set (self->apt_item,
+ DBUSMENU_MENUITEM_PROP_LABEL,
+ _("Software Up to Date"));
+ }
+ g_ptr_array_unref (packages);
+ g_object_unref (results);
+ g_object_unref (source_object);
}
static void
-apt_watcher_class_init (AptWatcherClass *klass)
+apt_watcher_check_for_updates (AptWatcher* self)
{
- GObjectClass* object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = apt_watcher_finalize;
+ PkClient* client;
+ client = pk_client_new ();
+
+ pk_client_get_updates_async (client,
+ PK_FILTER_ENUM_NONE,
+ NULL, NULL, NULL,
+ (GAsyncReadyCallback)get_updates_complete,
+ self);
}
-static void
-fetch_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data)
+static void apt_watcher_signal_cb ( GDBusProxy* proxy,
+ gchar* sender_name,
+ gchar* signal_name,
+ GVariant* parameters,
+ gpointer user_data)
{
- GError * error = NULL;
-
- AptWatcher* self = APT_WATCHER(user_data);
- g_return_if_fail(self != NULL);
-
- GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
-
- if (self->proxy_cancel != NULL) {
- g_object_unref(self->proxy_cancel);
- self->proxy_cancel = NULL;
- }
-
- if (error != NULL) {
- g_warning("Could not grab DBus proxy for %s: %s",
- "org.debian.apt", error->message);
- g_error_free(error);
- return;
- }
+ g_return_if_fail (APT_IS_WATCHER (user_data));
+ AptWatcher* self = APT_WATCHER (user_data);
- self->proxy = proxy;
- // Set up the watch.
- watcher_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
- "org.debian.apt",
- G_BUS_NAME_WATCHER_FLAGS_NONE,
- apt_watcher_on_name_appeared,
- apt_watcher_on_name_vanished,
- self,
- NULL);
-
- g_signal_connect (self->proxy,
- "g-signal",
- G_CALLBACK(apt_watcher_signal_cb),
- self);
+ g_debug ("apt-watcher-signal cb signal name - %s", signal_name);
+ if (g_strcmp0(signal_name, "UpdatesChanged") == 0){
+ g_debug ("updates changed signal received");
+ apt_watcher_check_for_updates (self);
+ }
+ else if (g_strcmp0(signal_name, "RestartScheduled") == 0) {
+ g_debug ("RestartScheduled signal received");
+ 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);
+ }
}
static void
@@ -170,21 +133,12 @@ apt_watcher_on_name_appeared (GDBusConnection *connection,
gpointer user_data)
{
g_return_if_fail (APT_IS_WATCHER (user_data));
- AptWatcher* watcher = APT_WATCHER (user_data);
+ // AptWatcher* watcher = APT_WATCHER (user_data);
g_print ("Name %s on %s is owned by %s\n",
name,
"the system bus",
name_owner);
-
- g_dbus_proxy_call (watcher->proxy,
- "UpgradeSystem",
- g_variant_new("(b)", TRUE),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- apt_watcher_upgrade_system_cb,
- user_data);
}
@@ -199,36 +153,61 @@ apt_watcher_on_name_vanished (GDBusConnection *connection,
}
static void
-apt_watcher_upgrade_system_cb (GObject * obj,
- GAsyncResult * res,
- gpointer user_data)
+fetch_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data)
{
- g_return_if_fail (APT_IS_WATCHER (user_data));
- AptWatcher* self = APT_WATCHER (user_data);
+ GError * error = NULL;
- GError * error = NULL;
- GVariant * result;
+ AptWatcher* self = APT_WATCHER(user_data);
+ g_return_if_fail(self != NULL);
- result = g_dbus_proxy_call_finish(self->proxy, res, &error);
+ GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
- if (error != NULL) {
- g_warning ("unable to complete the UpgradeSystem apt call");
- g_error_free (error);
- return;
- }
-
- gchar* transaction_id = NULL;
- g_variant_get (result, "(s)", &transaction_id);
+ if (self->proxy_cancel != NULL) {
+ g_object_unref (self->proxy_cancel);
+ self->proxy_cancel = NULL;
+ }
- if (transaction_id == NULL){
- g_warning ("apt_watcher_upgrade_system_cb - transaction id is null");
+ if (error != NULL) {
+ g_warning("Could not grab DBus proxy for %s: %s",
+ "org.debian.apt", error->message);
+ g_error_free(error);
return;
- }
-
- apt_watcher_manage_transactions (self, transaction_id);
-
+ }
+
+ self->proxy = proxy;
+ // Set up the watch.
+ watcher_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
+ "org.freedesktop.PackageKit",
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ apt_watcher_on_name_appeared,
+ apt_watcher_on_name_vanished,
+ self,
+ NULL);
+ g_signal_connect (self->proxy,
+ "g-signal",
+ G_CALLBACK(apt_watcher_signal_cb),
+ 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,
+ "org.freedesktop.PackageKit",
+ "/org/freedesktop/PackageKit",
+ "org.freedesktop.PackageKit",
+ self->proxy_cancel,
+ fetch_proxy_cb,
+ self);
+ apt_watcher_check_for_updates (self);
+ return FALSE;
}
+
static void
apt_watcher_show_apt_dialog (DbusmenuMenuitem * mi,
guint timestamp,
@@ -261,224 +240,31 @@ apt_watcher_show_apt_dialog (DbusmenuMenuitem * mi,
}
static void
-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 (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;
- }
- else{
- 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->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);
- }
- }
- }
-}
-
-
-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"));
- 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,
- _("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
-apt_watcher_manage_transactions (AptWatcher* self, gchar* transaction_id)
+apt_watcher_init (AptWatcher *self)
{
- if (self->current_transaction == NULL){
- 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_simulation_update_cb), self);
- }
+ self->current_state = UP_TO_DATE;
+ g_timeout_add_seconds (60,
+ apt_watcher_start_apt_interaction,
+ self);
}
-static gboolean
-apt_watcher_query_reboot_status (gpointer data)
+static void
+apt_watcher_finalize (GObject *object)
{
- 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 = FALSE;
- 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;
+ g_bus_unwatch_name (watcher_id);
+ AptWatcher* self = APT_WATCHER (object);
+
+ if (self->proxy != NULL)
+ g_object_unref (self->proxy);
+
+ G_OBJECT_CLASS (apt_watcher_parent_class)->finalize (object);
}
-static void apt_watcher_signal_cb ( GDBusProxy* proxy,
- gchar* sender_name,
- gchar* signal_name,
- GVariant* parameters,
- gpointer user_data)
+static void
+apt_watcher_class_init (AptWatcherClass *klass)
{
- g_return_if_fail (APT_IS_WATCHER (user_data));
- AptWatcher* self = APT_WATCHER (user_data);
-
- g_variant_ref_sink (parameters);
- GVariant *value = g_variant_get_child_value (parameters, 0);
-
- if (g_strcmp0(signal_name, "ActiveTransactionsChanged") == 0){
- gchar* current = NULL;
- g_debug ("ActiveTransactionsChanged");
-
- g_variant_get(value, "s", &current);
-
- 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 (current, REAL);
- g_signal_connect (G_OBJECT(self->current_transaction),
- "state-update",
- 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 (value);
- g_variant_unref (parameters);
+ GObjectClass* object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = apt_watcher_finalize;
}
AptWatcher* apt_watcher_new (SessionDbus* session_dbus,