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 }