comparison pui-backend.c @ 64:a5ed1047ce14

Obtain network state from GNetworkMonitor The PackageKit daemon does not necessarily run continuously and is therefore not a reliable source for network changes. More specifically, if the internet connectivity is not available when the PackageKit daemon shuts down, package-update-indicator will not be notified if connectivity is restored. Thus use GNetworkMonitor instead which is also used internally by PackageKit. This change is based on patches by Cliff <cliffd@gmx.com.br> who discovered and tracked down this issue.
author Guido Berhoerster <guido+pui@berhoerster.name>
date Sun, 14 Jan 2024 18:53:37 +0100
parents 8ed91c5e0116
children 72f0eea06b7c
comparison
equal deleted inserted replaced
63:9a6836ab0bc7 64:a5ed1047ce14
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */ 22 */
23 23
24 #include <errno.h> 24 #include <errno.h>
25 #include <fcntl.h> 25 #include <fcntl.h>
26 #include <gio/gio.h>
26 #include <packagekit-glib2/packagekit.h> 27 #include <packagekit-glib2/packagekit.h>
27 #include <polkit/polkit.h> 28 #include <polkit/polkit.h>
28 #include <string.h> 29 #include <string.h>
29 #include <sys/stat.h> 30 #include <sys/stat.h>
30 #include <sys/types.h> 31 #include <sys/types.h>
36 #include "pui-get-updates.h" 37 #include "pui-get-updates.h"
37 #include "pui-types.h" 38 #include "pui-types.h"
38 39
39 #define LOW_BATTERY_THRESHOLD 10.0 /* % */ 40 #define LOW_BATTERY_THRESHOLD 10.0 /* % */
40 #define UPDATES_CHANGED_UNBLOCK_DELAY 4 /* s */ 41 #define UPDATES_CHANGED_UNBLOCK_DELAY 4 /* s */
42
43 typedef enum {
44 NETWORK_STATE_OFFLINE,
45 NETWORK_STATE_ONLINE,
46 NETWORK_STATE_METERED,
47 NETWORK_STATE_LAST
48 } NetworkState;
49
50 static const gchar *network_state_strings[NETWORK_STATE_LAST] = {
51 [NETWORK_STATE_OFFLINE] = "offline",
52 [NETWORK_STATE_ONLINE] = "online",
53 [NETWORK_STATE_METERED] = "metered"
54 };
55
56 static const gchar *
57 network_state_to_string(NetworkState state)
58 {
59 g_assert(state > 0 && state < NETWORK_STATE_LAST);
60
61 return (network_state_strings[state]);
62 }
41 63
42 struct _PuiBackend { 64 struct _PuiBackend {
43 GObject parent_instance; 65 GObject parent_instance;
44 PkControl *pk_control; 66 PkControl *pk_control;
45 GCancellable *cancellable; 67 GCancellable *cancellable;
52 gchar *proxy_ftp; 74 gchar *proxy_ftp;
53 gchar *proxy_socks; 75 gchar *proxy_socks;
54 gchar *no_proxy; 76 gchar *no_proxy;
55 gchar *pac; 77 gchar *pac;
56 gint64 last_check; 78 gint64 last_check;
57 PkNetworkEnum network_state; 79 NetworkState network_state;
58 gboolean inhibited; 80 gboolean inhibited;
59 gboolean is_battery_low; 81 gboolean is_battery_low;
60 guint check_id; 82 guint check_id;
61 guint unblock_updates_changed_id; 83 guint unblock_updates_changed_id;
62 guint refresh_interval; 84 guint refresh_interval;
89 }; 111 };
90 112
91 static guint signals[SIGNAL_LAST] = { 0 }; 113 static guint signals[SIGNAL_LAST] = { 0 };
92 static GParamSpec *properties[PROP_LAST] = { NULL }; 114 static GParamSpec *properties[PROP_LAST] = { NULL };
93 115
116 static NetworkState get_network_state(GNetworkMonitor *);
94 static gboolean periodic_check(gpointer); 117 static gboolean periodic_check(gpointer);
95 static void on_updates_changed(PkControl *, gpointer); 118 static void on_updates_changed(PkControl *, gpointer);
96 119
97 GQuark 120 GQuark
98 pui_backend_error_quark(void) 121 pui_backend_error_quark(void)
255 gboolean is_disallowed_mobile; 278 gboolean is_disallowed_mobile;
256 gboolean inhibited; 279 gboolean inhibited;
257 guint elapsed_time; 280 guint elapsed_time;
258 guint remaining_time; 281 guint remaining_time;
259 282
260 is_offline = self->network_state == PK_NETWORK_ENUM_OFFLINE; 283 is_offline = self->network_state == NETWORK_STATE_OFFLINE;
261 is_disallowed_mobile = !self->use_mobile_connection && 284 is_disallowed_mobile = !self->use_mobile_connection &&
262 (self->network_state == PK_NETWORK_ENUM_MOBILE); 285 (self->network_state == NETWORK_STATE_METERED);
263 inhibited = is_offline || is_disallowed_mobile || self->is_battery_low; 286 inhibited = is_offline || is_disallowed_mobile || self->is_battery_low;
264 if (self->inhibited == inhibited) { 287 if (self->inhibited == inhibited) {
265 return; 288 return;
266 } 289 }
267 290
490 513
491 self->up_client = up_client_new(); 514 self->up_client = up_client_new();
492 if (self->up_client) { 515 if (self->up_client) {
493 self->up_device = up_client_get_display_device(self->up_client); 516 self->up_device = up_client_get_display_device(self->up_client);
494 } 517 }
518
519 self->network_state =
520 get_network_state(g_network_monitor_get_default());
495 } 521 }
496 522
497 static void 523 static void
498 on_get_properties_finished(GObject *object, GAsyncResult *result, 524 on_get_properties_finished(GObject *object, GAsyncResult *result,
499 gpointer user_data) 525 gpointer user_data)
513 goto out; 539 goto out;
514 } 540 }
515 541
516 /* check whether the backend supports GetUpdates */ 542 /* check whether the backend supports GetUpdates */
517 g_object_get(control, "backend-name", &backend_name, "roles", &roles, 543 g_object_get(control, "backend-name", &backend_name, "roles", &roles,
518 "network-state", &self->network_state, NULL); 544 NULL);
519 g_debug("backend: %s", backend_name); 545 g_debug("backend: %s", backend_name);
520 roles_str = pk_role_bitfield_to_string(roles); 546 roles_str = pk_role_bitfield_to_string(roles);
521 g_debug("roles: %s", roles_str); 547 g_debug("roles: %s", roles_str);
522 g_debug("network-state: %s", 548 g_debug("network-state: %s",
523 pk_network_enum_to_string(self->network_state)); 549 network_state_to_string(self->network_state));
524 if (!pk_bitfield_contain(roles, PK_ROLE_ENUM_GET_UPDATES)) { 550 if (!pk_bitfield_contain(roles, PK_ROLE_ENUM_GET_UPDATES)) {
525 error = g_error_new(PUI_BACKEND_ERROR, 551 error = g_error_new(PUI_BACKEND_ERROR,
526 PUI_BACKEND_ERROR_GET_UPDATES_NOT_IMPLEMENTED, 552 PUI_BACKEND_ERROR_GET_UPDATES_NOT_IMPLEMENTED,
527 "Getting updates is not implemented in the %s PackageKit " 553 "Getting updates is not implemented in the %s PackageKit "
528 "backend", backend_name); 554 "backend", backend_name);
555 self->is_battery_low = !self->is_battery_low; 581 self->is_battery_low = !self->is_battery_low;
556 check_inhibit(self); 582 check_inhibit(self);
557 } 583 }
558 } 584 }
559 585
560 static void 586 static NetworkState
561 on_notify_network_state(PkControl *pk_control, GParamSpec *pspec, 587 get_network_state(GNetworkMonitor *network_monitor)
562 gpointer user_data) 588 {
563 { 589 if (!g_network_monitor_get_network_available(network_monitor)) {
564 PuiBackend *self = user_data; 590 return (NETWORK_STATE_OFFLINE);
565 591 } else if (g_network_monitor_get_network_metered(network_monitor)) {
566 g_object_get(pk_control, "network-state", &self->network_state, NULL); 592 return (NETWORK_STATE_METERED);
593 }
594 return (NETWORK_STATE_ONLINE);
595 }
596
597 static void
598 on_network_changed(GNetworkMonitor *network_monitor,
599 gboolean network_available, gpointer user_data)
600 {
601 PuiBackend *self = user_data;
602 NetworkState network_state;
603
604 network_state = get_network_state(network_monitor);
605 if (network_state != self->network_state) {
606 return;
607 }
608 self->network_state = network_state;
567 g_debug("network state changed: %s", 609 g_debug("network state changed: %s",
568 pk_network_enum_to_string(self->network_state)); 610 network_state_to_string(self->network_state));
569 check_inhibit(self); 611 check_inhibit(self);
570 } 612 }
571 613
572 static void 614 static void
573 on_updates_changed(PkControl *control, gpointer user_data) 615 on_updates_changed(PkControl *control, gpointer user_data)
716 g_signal_connect(self->up_device, "notify::percentage", 758 g_signal_connect(self->up_device, "notify::percentage",
717 G_CALLBACK(on_notify_device_charge_percentage), self); 759 G_CALLBACK(on_notify_device_charge_percentage), self);
718 } 760 }
719 761
720 /* get notification when the network state changes */ 762 /* get notification when the network state changes */
721 g_signal_connect(self->pk_control, "notify::network-state", 763 g_signal_connect(g_network_monitor_get_default(), "network-changed",
722 G_CALLBACK(on_notify_network_state), self); 764 G_CALLBACK(on_network_changed), self);
723 /* get notifications when the package metatdata cache is invalidated */ 765 /* get notifications when the package metatdata cache is invalidated */
724 g_signal_connect(self->pk_control, "updates-changed", 766 g_signal_connect(self->pk_control, "updates-changed",
725 G_CALLBACK(on_updates_changed), self); 767 G_CALLBACK(on_updates_changed), self);
726 /* get notifications when an application restart is required */ 768 /* get notifications when an application restart is required */
727 g_signal_connect(self->pk_control, "restart-schedule", 769 g_signal_connect(self->pk_control, "restart-schedule",