Mercurial > projects > package-update-indicator
comparison pui-backend.c @ 10:adba37525ee5
Notify about required session or system restarts
Follow all PackageKit transactions and indicate when a session or system
restart is required.
Generate enum types with glib-mkenums.
author | Guido Berhoerster <guido+pui@berhoerster.name> |
---|---|
date | Fri, 06 Jul 2018 14:12:46 +0200 |
parents | 2477a6151087 |
children | 9905d4ae351c |
comparison
equal
deleted
inserted
replaced
9:b571e7ade208 | 10:adba37525ee5 |
---|---|
32 #include <utime.h> | 32 #include <utime.h> |
33 | 33 |
34 #include "pui-common.h" | 34 #include "pui-common.h" |
35 #include "pui-backend.h" | 35 #include "pui-backend.h" |
36 #include "pui-get-updates.h" | 36 #include "pui-get-updates.h" |
37 #include "pui-types.h" | |
37 | 38 |
38 #define LOW_BATTERY_THRESHOLD 10.0 | 39 #define LOW_BATTERY_THRESHOLD 10.0 |
39 | 40 |
40 struct _PuiBackend { | 41 struct _PuiBackend { |
41 GObject parent_instance; | 42 GObject parent_instance; |
42 PkControl *pk_control; | 43 PkControl *pk_control; |
43 GCancellable *cancellable; | 44 GCancellable *cancellable; |
45 PkClient *pk_client; | |
46 PkTransactionList *transaction_list; | |
44 UpClient *up_client; | 47 UpClient *up_client; |
45 UpDevice *up_device; | 48 UpDevice *up_device; |
46 gchar *proxy_http; | 49 gchar *proxy_http; |
47 gchar *proxy_https; | 50 gchar *proxy_https; |
48 gchar *proxy_ftp; | 51 gchar *proxy_ftp; |
56 guint periodic_check_id; | 59 guint periodic_check_id; |
57 guint refresh_interval; | 60 guint refresh_interval; |
58 gboolean use_mobile_connection; | 61 gboolean use_mobile_connection; |
59 guint important_updates; | 62 guint important_updates; |
60 guint normal_updates; | 63 guint normal_updates; |
64 PuiRestart restart_type; | |
61 }; | 65 }; |
62 | 66 |
63 static void pui_backend_async_initable_iface_init(gpointer, gpointer); | 67 static void pui_backend_async_initable_iface_init(gpointer, gpointer); |
64 | 68 |
65 G_DEFINE_TYPE_WITH_CODE(PuiBackend, pui_backend, G_TYPE_OBJECT, | 69 G_DEFINE_TYPE_WITH_CODE(PuiBackend, pui_backend, G_TYPE_OBJECT, |
74 | 78 |
75 enum { | 79 enum { |
76 PROP_0, | 80 PROP_0, |
77 PROP_IMPORTANT_UPDATES, | 81 PROP_IMPORTANT_UPDATES, |
78 PROP_NORMAL_UPDATES, | 82 PROP_NORMAL_UPDATES, |
83 PROP_RESTART_TYPE, | |
79 PROP_REFRESH_INTERVAL, | 84 PROP_REFRESH_INTERVAL, |
80 PROP_USE_MOBILE_CONNECTION, | 85 PROP_USE_MOBILE_CONNECTION, |
81 PROP_LAST | 86 PROP_LAST |
82 }; | 87 }; |
83 | 88 |
274 g_value_set_uint(value, self->important_updates); | 279 g_value_set_uint(value, self->important_updates); |
275 break; | 280 break; |
276 case PROP_NORMAL_UPDATES: | 281 case PROP_NORMAL_UPDATES: |
277 g_value_set_uint(value, self->normal_updates); | 282 g_value_set_uint(value, self->normal_updates); |
278 break; | 283 break; |
284 case PROP_RESTART_TYPE: | |
285 g_value_set_enum(value, self->restart_type); | |
286 break; | |
279 case PROP_REFRESH_INTERVAL: | 287 case PROP_REFRESH_INTERVAL: |
280 g_value_set_uint(value, self->refresh_interval); | 288 g_value_set_uint(value, self->refresh_interval); |
281 break; | 289 break; |
282 case PROP_USE_MOBILE_CONNECTION: | 290 case PROP_USE_MOBILE_CONNECTION: |
283 g_value_set_boolean(value, self->use_mobile_connection); | 291 g_value_set_boolean(value, self->use_mobile_connection); |
294 PuiBackend *self = PUI_BACKEND(object); | 302 PuiBackend *self = PUI_BACKEND(object); |
295 | 303 |
296 if (self->periodic_check_id != 0) { | 304 if (self->periodic_check_id != 0) { |
297 g_source_remove(self->periodic_check_id); | 305 g_source_remove(self->periodic_check_id); |
298 self->periodic_check_id = 0; | 306 self->periodic_check_id = 0; |
307 } | |
308 | |
309 if (self->transaction_list != NULL) { | |
310 g_clear_object(&self->transaction_list); | |
311 } | |
312 | |
313 if (self->pk_client != NULL) { | |
314 g_clear_object(&self->pk_client); | |
299 } | 315 } |
300 | 316 |
301 if (self->cancellable != NULL) { | 317 if (self->cancellable != NULL) { |
302 g_cancellable_cancel(self->cancellable); | 318 g_cancellable_cancel(self->cancellable); |
303 g_clear_object(&self->cancellable); | 319 g_clear_object(&self->cancellable); |
351 properties[PROP_NORMAL_UPDATES] = | 367 properties[PROP_NORMAL_UPDATES] = |
352 g_param_spec_uint("normal-updates", "Normal updates", | 368 g_param_spec_uint("normal-updates", "Normal updates", |
353 "Number of available normal updates", 0, G_MAXUINT, 0, | 369 "Number of available normal updates", 0, G_MAXUINT, 0, |
354 G_PARAM_READABLE); | 370 G_PARAM_READABLE); |
355 | 371 |
372 properties[PROP_RESTART_TYPE] = | |
373 g_param_spec_enum("restart-type", "Type of restart required", | |
374 "The Type of restart required", PUI_TYPE_RESTART, PUI_RESTART_NONE, | |
375 G_PARAM_READABLE); | |
376 | |
356 properties[PROP_REFRESH_INTERVAL] = | 377 properties[PROP_REFRESH_INTERVAL] = |
357 g_param_spec_uint("refresh-interval", "Refresh interval", | 378 g_param_spec_uint("refresh-interval", "Refresh interval", |
358 "Interval in seconds for refreshing the package cache", 0, | 379 "Interval in seconds for refreshing the package cache", 0, |
359 G_MAXUINT, PUI_DEFAULT_REFRESH_INTERVAL, G_PARAM_READWRITE); | 380 G_MAXUINT, PUI_DEFAULT_REFRESH_INTERVAL, G_PARAM_READWRITE); |
360 | 381 |
379 | 400 |
380 static void | 401 static void |
381 pui_backend_init(PuiBackend *self) | 402 pui_backend_init(PuiBackend *self) |
382 { | 403 { |
383 self->pk_control = pk_control_new(); | 404 self->pk_control = pk_control_new(); |
405 | |
406 self->pk_client = pk_client_new(); | |
384 | 407 |
385 self->inhibited = TRUE; | 408 self->inhibited = TRUE; |
386 | 409 |
387 self->up_client = up_client_new(); | 410 self->up_client = up_client_new(); |
388 if (self->up_client) { | 411 if (self->up_client) { |
468 static void | 491 static void |
469 on_updates_changed(PkControl *control, gpointer user_data) | 492 on_updates_changed(PkControl *control, gpointer user_data) |
470 { | 493 { |
471 PuiBackend *self = user_data; | 494 PuiBackend *self = user_data; |
472 | 495 |
496 g_debug("number of updates changed"); | |
497 | |
473 /* | 498 /* |
474 * schedule a check after a short delay so that a rapid succession of | 499 * schedule a check after a short delay so that a rapid succession of |
475 * signals is coalesced | 500 * signals is coalesced |
476 */ | 501 */ |
477 if (!self->inhibited) { | 502 if (!self->inhibited) { |
487 static void | 512 static void |
488 on_restart_schedule(PkControl *control, gpointer user_data) | 513 on_restart_schedule(PkControl *control, gpointer user_data) |
489 { | 514 { |
490 PuiBackend *self = user_data; | 515 PuiBackend *self = user_data; |
491 | 516 |
517 /* | |
518 * do not restart package-update-indicator if a session or system | |
519 * restart is required since that iformation would be lost across the | |
520 * restart, rather keep running and risk errors when interacting with | |
521 * a newer version of the PackageKit daemon | |
522 */ | |
523 if (self->restart_type > PUI_RESTART_NONE) { | |
524 return; | |
525 } | |
526 | |
492 g_debug("emitting signal restart-required"); | 527 g_debug("emitting signal restart-required"); |
493 g_signal_emit(self, signals[RESTART_REQUIRED], 0); | 528 g_signal_emit(self, signals[RESTART_REQUIRED], 0); |
529 } | |
530 | |
531 static void | |
532 on_transaction_adopt_finish(GObject *source_object, GAsyncResult *result, | |
533 gpointer user_data) | |
534 { | |
535 PuiBackend *self = user_data; | |
536 PkClient *pk_client = PK_CLIENT(source_object); | |
537 PkResults *results; | |
538 GError *error = NULL; | |
539 PkRestartEnum restart; | |
540 | |
541 results = pk_client_generic_finish(pk_client, result, &error); | |
542 if (results == NULL) { | |
543 g_warning("failed to get transaction results: %s", | |
544 error->message); | |
545 g_error_free(error); | |
546 goto out; | |
547 } | |
548 | |
549 /* check if transaction requires a restart */ | |
550 restart = pk_results_get_require_restart_worst(results); | |
551 switch (restart) { | |
552 case PK_RESTART_ENUM_SESSION: /* FALLTHROUGH */ | |
553 case PK_RESTART_ENUM_SECURITY_SESSION: | |
554 if (self->restart_type < PUI_RESTART_SESSION) { | |
555 self->restart_type = PUI_RESTART_SESSION; | |
556 g_object_notify_by_pspec(G_OBJECT(self), | |
557 properties[PROP_RESTART_TYPE]); | |
558 g_signal_emit(self, signals[STATE_CHANGED], 0); | |
559 } | |
560 break; | |
561 case PK_RESTART_ENUM_SYSTEM: /* FALLTHROUGH */ | |
562 case PK_RESTART_ENUM_SECURITY_SYSTEM: | |
563 if (self->restart_type < PUI_RESTART_SYSTEM) { | |
564 self->restart_type = PUI_RESTART_SYSTEM; | |
565 g_object_notify_by_pspec(G_OBJECT(self), | |
566 properties[PROP_RESTART_TYPE]); | |
567 g_signal_emit(self, signals[STATE_CHANGED], 0); | |
568 } | |
569 break; | |
570 default: | |
571 /* do nothing */ | |
572 break; | |
573 } | |
574 | |
575 g_debug("transaction finished, required restart: %s", | |
576 pk_restart_enum_to_string(restart)); | |
577 | |
578 out: | |
579 if (results != NULL) { | |
580 g_object_unref(results); | |
581 } | |
582 } | |
583 | |
584 static void | |
585 on_transaction_list_added(PkTransactionList *transaction_list, | |
586 const gchar *transaction_id, gpointer user_data) | |
587 { | |
588 PuiBackend *self = user_data; | |
589 | |
590 /* adopt transaction in order to monitor it for restart requirements */ | |
591 pk_client_adopt_async(self->pk_client, transaction_id, NULL, NULL, | |
592 NULL, on_transaction_adopt_finish, user_data); | |
494 } | 593 } |
495 | 594 |
496 static void | 595 static void |
497 pui_backend_init_async(GAsyncInitable *initable, int io_priority, | 596 pui_backend_init_async(GAsyncInitable *initable, int io_priority, |
498 GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) | 597 GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) |
544 g_signal_connect(self->pk_control, "updates-changed", | 643 g_signal_connect(self->pk_control, "updates-changed", |
545 G_CALLBACK(on_updates_changed), self); | 644 G_CALLBACK(on_updates_changed), self); |
546 /* get notifications when an application restart is required */ | 645 /* get notifications when an application restart is required */ |
547 g_signal_connect(self->pk_control, "restart-schedule", | 646 g_signal_connect(self->pk_control, "restart-schedule", |
548 G_CALLBACK(on_restart_schedule), self); | 647 G_CALLBACK(on_restart_schedule), self); |
648 /* get notifications when a transactions are added */ | |
649 self->transaction_list = pk_transaction_list_new(); | |
650 g_signal_connect(self->transaction_list, "added", | |
651 G_CALLBACK(on_transaction_list_added), self); | |
549 | 652 |
550 check_inhibit(self); | 653 check_inhibit(self); |
551 | 654 |
552 return (TRUE); | 655 return (TRUE); |
553 } | 656 } |