Mercurial > projects > package-update-indicator
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", |