~ubuntu-branches/ubuntu/quantal/indicator-session/quantal

« back to all changes in this revision

Viewing changes to src/apt-watcher.c

  • Committer: Package Import Robot
  • Author(s): Sebastien Bacher, Ken VanDine
  • Date: 2012-02-14 18:49:02 UTC
  • mfrom: (1.1.46)
  • Revision ID: package-import@ubuntu.com-20120214184902-uf9zw55ys3x2v7za
Tags: 0.3.91-0ubuntu1

* Backport "Don't lock the session when switching to another one"
  work from Robert Ancell, the screen locking is already done by 
  consolekit and enforcing it there is problematic to i.e use the 
  lightdm greeter as a lock screen (lp: #878836)
* debian/control:
  - recommends python-aptdaemon.pkcompat so packagekit doesn't get installed
* debian/source/format:
  - use v1, v3 doesn't play nicely with vcs backports

[ Ken VanDine ]
* New upstream release. (lp: #903756)
* debian/control
  - added new build depends on libpackagekit-glib2-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
with this program.  If not, see <http://www.gnu.org/licenses/>.
18
18
*/
19
19
 
20
 
#include <gio/gio.h>
 
20
// Conor - 6/2/2012
 
21
// Please pull in packagekit's client lib
 
22
// using apt-get install --no-install-recommends libpackagekit-glib2-dev
 
23
// make sure you don't install package-kit
 
24
#define I_KNOW_THE_PACKAGEKIT_GLIB2_API_IS_SUBJECT_TO_CHANGE
 
25
 
21
26
#include <glib/gi18n.h>
 
27
#include <packagekit-glib2/packagekit.h>
22
28
#include "apt-watcher.h"
23
 
#include "apt-transaction.h"
 
29
#include "dbus-shared-names.h"
24
30
 
25
31
static guint watcher_id;
26
32
 
27
33
struct _AptWatcher
28
34
{
29
35
        GObject parent_instance;
30
 
  guint reboot_query;
31
 
        GCancellable * proxy_cancel;
32
 
        GDBusProxy * proxy;  
33
36
  SessionDbus* session_dbus_interface;
34
37
  DbusmenuMenuitem* apt_item;
35
38
  AptState current_state;
36
 
  AptTransaction* current_transaction;
 
39
  GCancellable * proxy_cancel;
 
40
  GDBusProxy * proxy;
37
41
};
38
 
 
39
 
static void
40
 
apt_watcher_on_name_appeared (GDBusConnection *connection,
41
 
                              const gchar     *name,
42
 
                              const gchar     *name_owner,
43
 
                              gpointer         user_data);
44
 
static void
45
 
apt_watcher_on_name_vanished (GDBusConnection *connection,
46
 
                              const gchar     *name,
47
 
                              gpointer         user_data);
48
 
static void fetch_proxy_cb (GObject * object,
49
 
                            GAsyncResult * res,
50
 
                            gpointer user_data);
51
 
 
52
 
static void apt_watcher_upgrade_system_cb (GObject * obj,
53
 
                                           GAsyncResult * res,
54
 
                                           gpointer user_data);
55
 
                                                 
56
 
                
57
 
static void apt_watcher_show_apt_dialog (DbusmenuMenuitem* mi,
58
 
                                         guint timestamp,
59
 
                                         gpointer userdata);
60
 
 
61
 
static void apt_watcher_signal_cb (GDBusProxy* proxy,
62
 
                                   gchar* sender_name,
63
 
                                   gchar* signal_name,
64
 
                                   GVariant* parameters,
65
 
                                   gpointer user_data);
66
 
static void  apt_watcher_manage_transactions (AptWatcher* self,
67
 
                                              gchar* transaction_id);
68
 
static gboolean apt_watcher_query_reboot_status (gpointer self);
69
 
static void apt_watcher_transaction_state_simulation_update_cb (AptTransaction* trans,
70
 
                                                                gint update,
71
 
                                                                gpointer user_data);
72
 
static void apt_watcher_transaction_state_real_update_cb (AptTransaction* trans,
73
 
                                                          gint update,
74
 
                                                          gpointer user_data);                                   
75
 
static gboolean apt_watcher_start_apt_interaction (gpointer data);
76
 
 
 
42
                                                                
77
43
G_DEFINE_TYPE (AptWatcher, apt_watcher, G_TYPE_OBJECT);
78
44
 
79
 
static void
80
 
apt_watcher_init (AptWatcher *self)
81
 
{
82
 
  self->current_state = UP_TO_DATE;
83
 
  self->proxy_cancel = g_cancellable_new();
84
 
  self->proxy = NULL;
85
 
  self->reboot_query = 0;
86
 
  self->current_transaction = NULL;  
87
 
  g_timeout_add_seconds (60,
88
 
                         apt_watcher_start_apt_interaction,
89
 
                         self);   
90
 
}
91
 
 
92
 
static gboolean 
93
 
apt_watcher_start_apt_interaction (gpointer data)
94
 
{
95
 
  g_return_val_if_fail (APT_IS_WATCHER (data), FALSE);
96
 
  AptWatcher* self = APT_WATCHER (data);
97
 
  g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
98
 
                            G_DBUS_PROXY_FLAGS_NONE,
99
 
                            NULL,
100
 
                            "org.debian.apt",
101
 
                            "/org/debian/apt",
102
 
                            "org.debian.apt",
103
 
                            self->proxy_cancel,
104
 
                            fetch_proxy_cb,
105
 
                            self);
106
 
  return FALSE;    
107
 
}
108
 
 
109
 
static void
110
 
apt_watcher_finalize (GObject *object)
111
 
{
112
 
  g_bus_unwatch_name (watcher_id);  
113
 
  AptWatcher* self = APT_WATCHER (object);
114
 
           
115
 
  if (self->proxy != NULL)
116
 
    g_object_unref (self->proxy);
117
 
 
118
 
        G_OBJECT_CLASS (apt_watcher_parent_class)->finalize (object);
119
 
}
120
 
 
121
 
static void
122
 
apt_watcher_class_init (AptWatcherClass *klass)
123
 
{
124
 
        GObjectClass* object_class = G_OBJECT_CLASS (klass);
125
 
        object_class->finalize = apt_watcher_finalize;
 
45
 
 
46
static void
 
47
get_updates_complete (GObject *source_object,
 
48
                      GAsyncResult *res,
 
49
                      gpointer user_data)
 
50
{
 
51
  g_return_if_fail (APT_IS_WATCHER (user_data));
 
52
  AptWatcher* self = APT_WATCHER (user_data);
 
53
 
 
54
  PkResults *results;
 
55
  GError *error = NULL;
 
56
  results = pk_client_generic_finish (PK_CLIENT(source_object), res, &error);
 
57
  
 
58
  if (error != NULL){
 
59
    g_warning ("Unable to query for updates - error - %s", error->message);
 
60
    return;
 
61
  }
 
62
 
 
63
  GPtrArray *packages;
 
64
  packages = pk_results_get_package_array (results);
 
65
 
 
66
  const gchar* disposition;
 
67
  disposition = dbusmenu_menuitem_property_get (self->apt_item,
 
68
                                                DBUSMENU_MENUITEM_PROP_DISPOSITION);
 
69
  gboolean do_update;
 
70
  do_update = g_strcmp0 (disposition, DBUSMENU_MENUITEM_DISPOSITION_ALERT) != 0;                                       
 
71
 
 
72
  if (packages->len > 0){
 
73
    g_print ("Apparently we have updates available - change dbmitem %i", do_update);   
 
74
      if (do_update) 
 
75
        dbusmenu_menuitem_property_set (self->apt_item,
 
76
                                        DBUSMENU_MENUITEM_PROP_LABEL,
 
77
                                        _("Updates Available…"));    
 
78
  }
 
79
  else{
 
80
    g_print ("No updates available - change dbmitem - %i", do_update);   
 
81
      if (do_update)
 
82
        dbusmenu_menuitem_property_set (self->apt_item,
 
83
                                        DBUSMENU_MENUITEM_PROP_LABEL,
 
84
                                        _("Software Up to Date"));       
 
85
  }
 
86
  g_ptr_array_unref (packages);
 
87
  g_object_unref (results);
 
88
  g_object_unref (source_object);
 
89
}
 
90
 
 
91
static void
 
92
apt_watcher_check_for_updates (AptWatcher* self)
 
93
{
 
94
    PkClient* client;
 
95
    client = pk_client_new ();
 
96
 
 
97
    pk_client_get_updates_async (client, 
 
98
                                 PK_FILTER_ENUM_NONE,
 
99
                                 NULL, NULL, NULL,
 
100
                                 (GAsyncReadyCallback)get_updates_complete,
 
101
                                 self);  
 
102
}
 
103
 
 
104
static void apt_watcher_signal_cb ( GDBusProxy* proxy,
 
105
                                    gchar* sender_name,
 
106
                                    gchar* signal_name,
 
107
                                    GVariant* parameters,
 
108
                                    gpointer user_data)
 
109
{
 
110
  g_return_if_fail (APT_IS_WATCHER (user_data));
 
111
  AptWatcher* self = APT_WATCHER (user_data);
 
112
 
 
113
  g_debug ("apt-watcher-signal cb signal name - %s", signal_name);
 
114
  if (g_strcmp0(signal_name, "UpdatesChanged") == 0){
 
115
    g_debug ("updates changed signal received");
 
116
    apt_watcher_check_for_updates (self);
 
117
  }
 
118
  else if (g_strcmp0(signal_name, "RestartScheduled") == 0) {
 
119
    g_debug ("RestartScheduled signal received");
 
120
    dbusmenu_menuitem_property_set (self->apt_item,
 
121
                                    DBUSMENU_MENUITEM_PROP_LABEL,
 
122
                                    _("Restart to Complete Updates…"));
 
123
    dbusmenu_menuitem_property_set (self->apt_item,
 
124
                                    DBUSMENU_MENUITEM_PROP_DISPOSITION,
 
125
                                    DBUSMENU_MENUITEM_DISPOSITION_ALERT);     
 
126
  } 
 
127
}
 
128
 
 
129
static void
 
130
apt_watcher_on_name_appeared (GDBusConnection *connection,
 
131
                              const gchar     *name,
 
132
                              const gchar     *name_owner,
 
133
                              gpointer         user_data)
 
134
{
 
135
  g_return_if_fail (APT_IS_WATCHER (user_data));
 
136
 // AptWatcher* watcher = APT_WATCHER (user_data);
 
137
  
 
138
  g_print ("Name %s on %s is owned by %s\n",
 
139
           name,
 
140
           "the system bus",
 
141
           name_owner);
 
142
}
 
143
 
 
144
 
 
145
static void
 
146
apt_watcher_on_name_vanished (GDBusConnection *connection,
 
147
                              const gchar     *name,
 
148
                              gpointer         user_data)
 
149
{
 
150
  g_debug ("Name %s does not exist or has just vanished",
 
151
           name);
 
152
  g_return_if_fail (APT_IS_WATCHER (user_data));
126
153
}
127
154
 
128
155
static void
129
156
fetch_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data)
130
157
{
131
 
        GError * error = NULL;
132
 
 
133
 
        AptWatcher* self = APT_WATCHER(user_data);
134
 
        g_return_if_fail(self != NULL);
135
 
 
136
 
        GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
137
 
 
138
 
        if (self->proxy_cancel != NULL) {
139
 
                g_object_unref(self->proxy_cancel);
140
 
                self->proxy_cancel = NULL;
141
 
        }
142
 
 
143
 
        if (error != NULL) {
144
 
                g_warning("Could not grab DBus proxy for %s: %s",
 
158
  GError * error = NULL;
 
159
 
 
160
  AptWatcher* self = APT_WATCHER(user_data);
 
161
  g_return_if_fail(self != NULL);
 
162
 
 
163
  GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
 
164
 
 
165
  if (self->proxy_cancel != NULL) {
 
166
    g_object_unref (self->proxy_cancel);
 
167
    self->proxy_cancel = NULL;
 
168
  }
 
169
 
 
170
  if (error != NULL) {
 
171
    g_warning("Could not grab DBus proxy for %s: %s",
145
172
               "org.debian.apt", error->message);
146
 
                g_error_free(error);
147
 
                return;
148
 
        }
 
173
    g_error_free(error);
 
174
    return;
 
175
  }
149
176
 
150
 
        self->proxy = proxy;
 
177
  self->proxy = proxy;
151
178
  // Set up the watch.
152
179
  watcher_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
153
 
                                 "org.debian.apt",
 
180
                                 "org.freedesktop.PackageKit",
154
181
                                 G_BUS_NAME_WATCHER_FLAGS_NONE,
155
182
                                 apt_watcher_on_name_appeared,
156
183
                                 apt_watcher_on_name_vanished,
157
184
                                 self,
158
 
                                 NULL);
159
 
  
160
 
        g_signal_connect (self->proxy,
 
185
                                 NULL);  
 
186
  g_signal_connect (self->proxy,
161
187
                    "g-signal",
162
188
                    G_CALLBACK(apt_watcher_signal_cb),
163
189
                    self);   
164
190
}
165
191
 
166
 
static void
167
 
apt_watcher_on_name_appeared (GDBusConnection *connection,
168
 
                              const gchar     *name,
169
 
                              const gchar     *name_owner,
170
 
                              gpointer         user_data)
171
 
{
172
 
  g_return_if_fail (APT_IS_WATCHER (user_data));
173
 
  AptWatcher* watcher = APT_WATCHER (user_data);
174
 
  
175
 
  g_print ("Name %s on %s is owned by %s\n",
176
 
           name,
177
 
           "the system bus",
178
 
           name_owner);
179
 
 
180
 
  g_dbus_proxy_call (watcher->proxy,
181
 
                     "UpgradeSystem",
182
 
                     g_variant_new("(b)", TRUE),
183
 
                     G_DBUS_CALL_FLAGS_NONE,
184
 
                     -1,
185
 
                     NULL,
186
 
                     apt_watcher_upgrade_system_cb,
187
 
                     user_data);                  
188
 
}
189
 
 
190
 
 
191
 
static void
192
 
apt_watcher_on_name_vanished (GDBusConnection *connection,
193
 
                              const gchar     *name,
194
 
                              gpointer         user_data)
195
 
{
196
 
  g_debug ("Name %s does not exist or has just vanished",
197
 
           name);
198
 
  g_return_if_fail (APT_IS_WATCHER (user_data));
199
 
}
200
 
 
201
 
static void
202
 
apt_watcher_upgrade_system_cb (GObject * obj,
203
 
                               GAsyncResult * res,
204
 
                               gpointer user_data)
205
 
{
206
 
  g_return_if_fail (APT_IS_WATCHER (user_data));
207
 
  AptWatcher* self = APT_WATCHER (user_data);
208
 
 
209
 
        GError * error = NULL;
210
 
        GVariant * result;
211
 
 
212
 
        result = g_dbus_proxy_call_finish(self->proxy, res, &error);
213
 
 
214
 
        if (error != NULL) {
215
 
    g_warning ("unable to complete the UpgradeSystem apt call");
216
 
    g_error_free (error);
217
 
                return;
218
 
        }
219
 
  
220
 
  gchar* transaction_id = NULL;
221
 
  g_variant_get (result, "(s)", &transaction_id);
222
 
 
223
 
  if (transaction_id == NULL){
224
 
    g_warning ("apt_watcher_upgrade_system_cb - transaction id is null");
225
 
    return;
226
 
  }  
227
 
  
228
 
  apt_watcher_manage_transactions (self, transaction_id);
229
 
  
230
 
}
 
192
static gboolean 
 
193
apt_watcher_start_apt_interaction (gpointer data)
 
194
{
 
195
  g_return_val_if_fail (APT_IS_WATCHER (data), FALSE);
 
196
  AptWatcher* self = APT_WATCHER (data);
 
197
  g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
 
198
                            G_DBUS_PROXY_FLAGS_NONE,
 
199
                            NULL,
 
200
                            "org.freedesktop.PackageKit",
 
201
                            "/org/freedesktop/PackageKit",
 
202
                            "org.freedesktop.PackageKit",
 
203
                            self->proxy_cancel,
 
204
                            fetch_proxy_cb,
 
205
                            self);
 
206
  apt_watcher_check_for_updates (self);
 
207
  return FALSE;    
 
208
}
 
209
 
231
210
 
232
211
static void
233
212
apt_watcher_show_apt_dialog (DbusmenuMenuitem * mi,
261
240
}
262
241
 
263
242
static void
264
 
apt_watcher_transaction_state_real_update_cb (AptTransaction* trans,
265
 
                                              gint update,
266
 
                                              gpointer user_data)
267
 
{
268
 
  g_debug ("apt-watcher -transaction update %i", update);
269
 
  g_return_if_fail (APT_IS_WATCHER (user_data));
270
 
  AptWatcher* self = APT_WATCHER (user_data);
271
 
  
272
 
  AptState state = (AptState)update;
273
 
  if (self->current_state != RESTART_NEEDED)
274
 
  {
275
 
    if (state == UP_TO_DATE){
276
 
      dbusmenu_menuitem_property_set (self->apt_item,
277
 
                                      DBUSMENU_MENUITEM_PROP_LABEL,
278
 
                                      _("Software Up to Date"));   
279
 
      self->current_state = state;                                                
280
 
    }
281
 
    else if (state == UPDATES_AVAILABLE){
282
 
      dbusmenu_menuitem_property_set (self->apt_item,
283
 
                                      DBUSMENU_MENUITEM_PROP_LABEL,
284
 
                                      _("Updates Available…"));    
285
 
      self->current_state = state;                                    
286
 
    }
287
 
    else if (state == UPGRADE_IN_PROGRESS){
288
 
      dbusmenu_menuitem_property_set (self->apt_item,
289
 
                                      DBUSMENU_MENUITEM_PROP_LABEL,
290
 
                                      _("Updates Installing…"));    
291
 
      self->current_state = state;                                    
292
 
    }  
293
 
    else if (state == FINISHED){
294
 
      gboolean query_again = FALSE;
295
 
      
296
 
      // Only query if the previous state was an upgrade.
297
 
      if (self->current_state != UPGRADE_IN_PROGRESS){
298
 
        query_again = TRUE;      
299
 
      }    
300
 
      else{
301
 
        if (self->reboot_query != 0){
302
 
          g_source_remove (self->reboot_query);
303
 
          self->reboot_query = 0;
304
 
        }
305
 
        self->reboot_query = g_timeout_add_seconds (1,
306
 
                                                    apt_watcher_query_reboot_status,
307
 
                                                    self);         
308
 
      }
309
 
      self->current_state = state;
310
 
 
311
 
      g_object_unref (G_OBJECT(self->current_transaction));
312
 
      self->current_transaction = NULL;
313
 
 
314
 
      // It is impossible to determine from a 'real' transaction whether
315
 
      // updates are available therefore it is necessary to check again via a 
316
 
      // simulation whether there are updates available. 
317
 
      if (query_again){
318
 
        g_dbus_proxy_call (self->proxy,
319
 
                           "UpgradeSystem",
320
 
                           g_variant_new("(b)", TRUE),
321
 
                           G_DBUS_CALL_FLAGS_NONE,
322
 
                           -1,
323
 
                           NULL,
324
 
                           apt_watcher_upgrade_system_cb,
325
 
                           self);
326
 
      }      
327
 
    }
328
 
  }
329
 
}                                              
330
 
 
331
 
 
332
 
static void
333
 
apt_watcher_transaction_state_simulation_update_cb (AptTransaction* trans,
334
 
                                                    gint update,
335
 
                                                    gpointer user_data)
336
 
{
337
 
  g_debug ("apt-watcher -transaction update %i", update);
338
 
  g_return_if_fail (APT_IS_WATCHER (user_data));
339
 
  AptWatcher* self = APT_WATCHER (user_data);
340
 
  
341
 
  AptState state = (AptState)update;
342
 
  if (self->current_state != RESTART_NEEDED)
343
 
  {
344
 
    if (state == UP_TO_DATE){
345
 
      dbusmenu_menuitem_property_set (self->apt_item,
346
 
                                      DBUSMENU_MENUITEM_PROP_LABEL,
347
 
                                      _("Software Up to Date"));   
348
 
      if (self->reboot_query != 0){
349
 
        g_source_remove (self->reboot_query);
350
 
        self->reboot_query = 0;
351
 
      }
352
 
      self->reboot_query = g_timeout_add_seconds (1,
353
 
                                                  apt_watcher_query_reboot_status,
354
 
                                                  self); 
355
 
    }
356
 
    else if (state == UPDATES_AVAILABLE){
357
 
      dbusmenu_menuitem_property_set (self->apt_item,
358
 
                                      DBUSMENU_MENUITEM_PROP_LABEL,
359
 
                                      _("Updates Available…"));    
360
 
    }
361
 
    else if (state == UPGRADE_IN_PROGRESS){
362
 
      dbusmenu_menuitem_property_set (self->apt_item,
363
 
                                      DBUSMENU_MENUITEM_PROP_LABEL,
364
 
                                      _("Updates Installing…"));    
365
 
    }  
366
 
    self->current_state = state;
367
 
  }  
368
 
  if (self->current_state != UPGRADE_IN_PROGRESS){
369
 
    g_object_unref (G_OBJECT(self->current_transaction));
370
 
    self->current_transaction = NULL;
371
 
  }
372
 
373
 
 
374
 
static void
375
 
apt_watcher_manage_transactions (AptWatcher* self, gchar* transaction_id)
376
 
{
377
 
    if (self->current_transaction == NULL){
378
 
      self->current_transaction = apt_transaction_new (transaction_id, SIMULATION);
379
 
      g_signal_connect (G_OBJECT(self->current_transaction),
380
 
                        "state-update",
381
 
                        G_CALLBACK(apt_watcher_transaction_state_simulation_update_cb), self);
382
 
    }
383
 
}
384
 
 
385
 
static gboolean
386
 
apt_watcher_query_reboot_status (gpointer data)
387
 
{
388
 
  g_return_val_if_fail (APT_IS_WATCHER (data), FALSE);
389
 
  AptWatcher* self = APT_WATCHER (data);
390
 
  
391
 
  GVariant* reboot_result = g_dbus_proxy_get_cached_property (self->proxy,
392
 
                                                             "RebootRequired");
393
 
  gboolean reboot = FALSE;
394
 
  g_variant_get (reboot_result, "b", &reboot);
395
 
  g_debug ("apt_watcher_query_reboot_status: reboot prop = %i", reboot);
396
 
  if (reboot == FALSE){
397
 
    dbusmenu_menuitem_property_set (self->apt_item,
398
 
                                    DBUSMENU_MENUITEM_PROP_LABEL,
399
 
                                    _("Software Up to Date"));
400
 
    dbusmenu_menuitem_property_set (self->apt_item,
401
 
                                    DBUSMENU_MENUITEM_PROP_DISPOSITION,
402
 
                                    DBUSMENU_MENUITEM_DISPOSITION_NORMAL);
403
 
                                    
404
 
  }
405
 
  else{
406
 
    dbusmenu_menuitem_property_set (self->apt_item,
407
 
                                    DBUSMENU_MENUITEM_PROP_LABEL,
408
 
                                    _("Restart to Complete Updates…"));
409
 
    dbusmenu_menuitem_property_set (self->apt_item,
410
 
                                    DBUSMENU_MENUITEM_PROP_DISPOSITION,
411
 
                                    DBUSMENU_MENUITEM_DISPOSITION_ALERT);
412
 
    session_dbus_restart_required (self->session_dbus_interface);
413
 
    self->current_state = RESTART_NEEDED;
414
 
  }
415
 
  self->reboot_query = 0;
416
 
  return FALSE;
417
 
}
418
 
 
419
 
static void apt_watcher_signal_cb ( GDBusProxy* proxy,
420
 
                                    gchar* sender_name,
421
 
                                    gchar* signal_name,
422
 
                                    GVariant* parameters,
423
 
                                    gpointer user_data)
424
 
{
425
 
  g_return_if_fail (APT_IS_WATCHER (user_data));
426
 
  AptWatcher* self = APT_WATCHER (user_data);
427
 
 
428
 
  g_variant_ref_sink (parameters);
429
 
  GVariant *value = g_variant_get_child_value (parameters, 0);
430
 
 
431
 
  if (g_strcmp0(signal_name, "ActiveTransactionsChanged") == 0){
432
 
    gchar* current = NULL;
433
 
    g_debug ("ActiveTransactionsChanged");
434
 
 
435
 
    g_variant_get(value, "s", &current);
436
 
 
437
 
    if (g_str_has_prefix (current, "/org/debian/apt/transaction/") == TRUE){
438
 
      g_debug ("ActiveTransactionsChanged - current is %s", current);
439
 
     
440
 
      // Cancel all existing operations.
441
 
      if (self->reboot_query != 0){
442
 
        g_source_remove (self->reboot_query);
443
 
        self->reboot_query = 0;
444
 
      }
445
 
 
446
 
      if (self->current_transaction != NULL)
447
 
      {
448
 
        g_object_unref (G_OBJECT(self->current_transaction));
449
 
        self->current_transaction = NULL;
450
 
      }
451
 
 
452
 
      self->current_transaction = apt_transaction_new (current, REAL);
453
 
      g_signal_connect (G_OBJECT(self->current_transaction),
454
 
                        "state-update",
455
 
                        G_CALLBACK(apt_watcher_transaction_state_real_update_cb), self);              
456
 
    }
457
 
  }
458
 
  else if (g_strcmp0(signal_name, "PropertyChanged") == 0) 
459
 
  {
460
 
    gchar* prop_name= NULL;
461
 
    GVariant* value = NULL;
462
 
    g_variant_get (parameters, "(sv)", &prop_name, &value);    
463
 
    g_debug ("transaction prop update - prop = %s", prop_name);    
464
 
    
465
 
    if (g_strcmp0 (prop_name, "RebootRequired") == 0){
466
 
      gboolean reboot_required = FALSE;
467
 
      g_variant_get (value, "(b)", &reboot_required); 
468
 
      if (reboot_required){
469
 
        dbusmenu_menuitem_property_set (self->apt_item,
470
 
                                        DBUSMENU_MENUITEM_PROP_LABEL,
471
 
                                        _("Restart to Complete Updates…"));
472
 
        dbusmenu_menuitem_property_set (self->apt_item,
473
 
                                        DBUSMENU_MENUITEM_PROP_DISPOSITION,
474
 
                                        DBUSMENU_MENUITEM_DISPOSITION_ALERT); 
475
 
        self->current_state = RESTART_NEEDED;                                            
476
 
      }   
477
 
    }    
478
 
  } 
479
 
 
480
 
  g_variant_unref (value);
481
 
  g_variant_unref (parameters);
 
243
apt_watcher_init (AptWatcher *self)
 
244
{
 
245
  self->current_state = UP_TO_DATE;
 
246
  g_timeout_add_seconds (60,
 
247
                         apt_watcher_start_apt_interaction,
 
248
                         self); 
 
249
}
 
250
 
 
251
static void
 
252
apt_watcher_finalize (GObject *object)
 
253
{
 
254
  g_bus_unwatch_name (watcher_id);  
 
255
  AptWatcher* self = APT_WATCHER (object);
 
256
           
 
257
  if (self->proxy != NULL)
 
258
    g_object_unref (self->proxy);
 
259
         
 
260
  G_OBJECT_CLASS (apt_watcher_parent_class)->finalize (object);
 
261
}
 
262
 
 
263
static void
 
264
apt_watcher_class_init (AptWatcherClass *klass)
 
265
{
 
266
  GObjectClass* object_class = G_OBJECT_CLASS (klass);
 
267
  object_class->finalize = apt_watcher_finalize;
482
268
}
483
269
 
484
270
AptWatcher* apt_watcher_new (SessionDbus* session_dbus,