Mercurial > projects > package-update-indicator
comparison pui-backend.c @ 4:3d72ca76538d
Add setting to control whether to use a mobile connection
author | Guido Berhoerster <guido+pui@berhoerster.name> |
---|---|
date | Sun, 17 Jun 2018 11:05:28 +0200 |
parents | 6884bb8130ca |
children | a4020e99e550 |
comparison
equal
deleted
inserted
replaced
3:2fa34d6272c6 | 4:3d72ca76538d |
---|---|
37 GObject parent_instance; | 37 GObject parent_instance; |
38 PkControl *pk_control; | 38 PkControl *pk_control; |
39 GCancellable *cancellable; | 39 GCancellable *cancellable; |
40 gint64 last_check; | 40 gint64 last_check; |
41 PkNetworkEnum network_state; | 41 PkNetworkEnum network_state; |
42 gboolean inhibited; | |
42 guint periodic_check_id; | 43 guint periodic_check_id; |
43 guint refresh_interval; | 44 guint refresh_interval; |
45 gboolean use_mobile_connection; | |
44 guint important_updates; | 46 guint important_updates; |
45 guint normal_updates; | 47 guint normal_updates; |
46 }; | 48 }; |
47 | 49 |
48 static void pui_backend_async_initable_iface_init(gpointer, gpointer); | 50 static void pui_backend_async_initable_iface_init(gpointer, gpointer); |
60 enum { | 62 enum { |
61 PROP_0, | 63 PROP_0, |
62 PROP_IMPORTANT_UPDATES, | 64 PROP_IMPORTANT_UPDATES, |
63 PROP_NORMAL_UPDATES, | 65 PROP_NORMAL_UPDATES, |
64 PROP_REFRESH_INTERVAL, | 66 PROP_REFRESH_INTERVAL, |
67 PROP_USE_MOBILE_CONNECTION, | |
65 PROP_LAST | 68 PROP_LAST |
66 }; | 69 }; |
67 | 70 |
68 static guint signals[SIGNAL_LAST] = { 0 }; | 71 static guint signals[SIGNAL_LAST] = { 0 }; |
69 static GParamSpec *properties[PROP_LAST] = { NULL }; | 72 static GParamSpec *properties[PROP_LAST] = { NULL }; |
145 | 148 |
146 /* last successful check */ | 149 /* last successful check */ |
147 self->last_check = g_get_monotonic_time(); | 150 self->last_check = g_get_monotonic_time(); |
148 | 151 |
149 out: | 152 out: |
153 g_clear_object(&self->cancellable); | |
154 | |
150 /* reschedule periodic check */ | 155 /* reschedule periodic check */ |
151 if (self->network_state != PK_NETWORK_ENUM_OFFLINE) { | 156 if (!self->inhibited) { |
152 self->periodic_check_id = | 157 self->periodic_check_id = |
153 g_timeout_add_seconds(PUI_CHECK_UPDATES_INTERVAL, | 158 g_timeout_add_seconds(PUI_CHECK_UPDATES_INTERVAL, |
154 periodic_check, self); | 159 periodic_check, self); |
155 } | 160 } |
156 | 161 |
164 { | 169 { |
165 PuiBackend *self = user_data; | 170 PuiBackend *self = user_data; |
166 | 171 |
167 g_debug("running periodic check"); | 172 g_debug("running periodic check"); |
168 | 173 |
174 self->cancellable = g_cancellable_new(); | |
169 pui_get_updates_async(self->pk_control, self->refresh_interval, | 175 pui_get_updates_async(self->pk_control, self->refresh_interval, |
170 self->cancellable, on_get_updates_finished, self); | 176 self->cancellable, on_get_updates_finished, self); |
171 | 177 |
172 /* next periodic check will be scheduled after completion */ | 178 /* next periodic check will be scheduled after completion */ |
173 self->periodic_check_id = 0; | 179 self->periodic_check_id = 0; |
174 | 180 |
175 return (G_SOURCE_REMOVE); | 181 return (G_SOURCE_REMOVE); |
182 } | |
183 | |
184 static void | |
185 check_inhibit(PuiBackend *self) | |
186 { | |
187 gboolean inhibited; | |
188 guint elapsed_time; | |
189 guint remaining_time; | |
190 | |
191 inhibited = ((self->network_state == PK_NETWORK_ENUM_OFFLINE) || | |
192 (!self->use_mobile_connection && | |
193 (self->network_state == PK_NETWORK_ENUM_MOBILE))); | |
194 if (self->inhibited == inhibited) { | |
195 return; | |
196 } | |
197 | |
198 self->inhibited = inhibited; | |
199 if (inhibited) { | |
200 /* cancel periodic checks */ | |
201 if (self->periodic_check_id != 0) { | |
202 g_source_remove(self->periodic_check_id); | |
203 } | |
204 | |
205 /* cancel running operation */ | |
206 if ((self->cancellable != NULL) && | |
207 !g_cancellable_is_cancelled(self->cancellable)) { | |
208 g_cancellable_cancel(self->cancellable); | |
209 g_clear_object(&self->cancellable); | |
210 } | |
211 } else { | |
212 /* schedule periodic checks when no longer inhibited */ | |
213 elapsed_time = (g_get_monotonic_time() - self->last_check) / | |
214 G_USEC_PER_SEC; | |
215 /* | |
216 * if more time that the check interval has passed since the | |
217 * last check, schedule a check after a short delay, otherwise | |
218 * wait until the interval has passed | |
219 */ | |
220 remaining_time = (elapsed_time < PUI_CHECK_UPDATES_INTERVAL) ? | |
221 PUI_CHECK_UPDATES_INTERVAL - elapsed_time : | |
222 PUI_STARTUP_DELAY; | |
223 self->periodic_check_id = g_timeout_add_seconds(remaining_time, | |
224 periodic_check, self); | |
225 } | |
176 } | 226 } |
177 | 227 |
178 static void | 228 static void |
179 pui_backend_set_property(GObject *object, guint property_id, | 229 pui_backend_set_property(GObject *object, guint property_id, |
180 const GValue *value, GParamSpec *pspec) | 230 const GValue *value, GParamSpec *pspec) |
185 case PROP_REFRESH_INTERVAL: | 235 case PROP_REFRESH_INTERVAL: |
186 self->refresh_interval = g_value_get_uint(value); | 236 self->refresh_interval = g_value_get_uint(value); |
187 g_debug("property \"refresh-interval\" set to %u", | 237 g_debug("property \"refresh-interval\" set to %u", |
188 self->refresh_interval); | 238 self->refresh_interval); |
189 break; | 239 break; |
240 case PROP_USE_MOBILE_CONNECTION: | |
241 self->use_mobile_connection = g_value_get_boolean(value); | |
242 g_debug("property \"use-mobile-connection\" set to %s", | |
243 self->use_mobile_connection ? "true" : "false"); | |
244 check_inhibit(self); | |
245 break; | |
190 default: | 246 default: |
191 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); | 247 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); |
192 break; | 248 break; |
193 } | 249 } |
194 } | 250 } |
206 case PROP_NORMAL_UPDATES: | 262 case PROP_NORMAL_UPDATES: |
207 g_value_set_uint(value, self->normal_updates); | 263 g_value_set_uint(value, self->normal_updates); |
208 break; | 264 break; |
209 case PROP_REFRESH_INTERVAL: | 265 case PROP_REFRESH_INTERVAL: |
210 g_value_set_uint(value, self->refresh_interval); | 266 g_value_set_uint(value, self->refresh_interval); |
267 break; | |
268 case PROP_USE_MOBILE_CONNECTION: | |
269 g_value_set_boolean(value, self->use_mobile_connection); | |
211 break; | 270 break; |
212 default: | 271 default: |
213 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); | 272 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); |
214 break; | 273 break; |
215 } | 274 } |
259 properties[PROP_REFRESH_INTERVAL] = | 318 properties[PROP_REFRESH_INTERVAL] = |
260 g_param_spec_uint("refresh-interval", "Refresh interval", | 319 g_param_spec_uint("refresh-interval", "Refresh interval", |
261 "Interval in seconds for refreshing the package cache", 0, | 320 "Interval in seconds for refreshing the package cache", 0, |
262 G_MAXUINT, PUI_DEFAULT_REFRESH_INTERVAL, G_PARAM_READWRITE); | 321 G_MAXUINT, PUI_DEFAULT_REFRESH_INTERVAL, G_PARAM_READWRITE); |
263 | 322 |
323 properties[PROP_USE_MOBILE_CONNECTION] = | |
324 g_param_spec_boolean("use-mobile-connection", | |
325 "Whether to use a mobile connection", "Whether to use a mobile " | |
326 "connection for refreshing the package cache", FALSE, | |
327 G_PARAM_READWRITE); | |
328 | |
264 g_object_class_install_properties(object_class, PROP_LAST, properties); | 329 g_object_class_install_properties(object_class, PROP_LAST, properties); |
265 | 330 |
266 signals[STATE_CHANGED] = g_signal_new("state-changed", | 331 signals[STATE_CHANGED] = g_signal_new("state-changed", |
267 G_TYPE_FROM_CLASS(object_class), | 332 G_TYPE_FROM_CLASS(object_class), |
268 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, | 333 G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, 0, |
275 } | 340 } |
276 | 341 |
277 static void | 342 static void |
278 pui_backend_init(PuiBackend *self) | 343 pui_backend_init(PuiBackend *self) |
279 { | 344 { |
280 self->cancellable = g_cancellable_new(); | |
281 self->pk_control = pk_control_new(); | 345 self->pk_control = pk_control_new(); |
346 self->inhibited = TRUE; | |
282 } | 347 } |
283 | 348 |
284 static void | 349 static void |
285 on_get_properties_finished(GObject *object, GAsyncResult *result, | 350 on_get_properties_finished(GObject *object, GAsyncResult *result, |
286 gpointer user_data) | 351 gpointer user_data) |
327 static void | 392 static void |
328 on_notify_network_state(PkControl *pk_control, GParamSpec *pspec, | 393 on_notify_network_state(PkControl *pk_control, GParamSpec *pspec, |
329 gpointer user_data) | 394 gpointer user_data) |
330 { | 395 { |
331 PuiBackend *self = user_data; | 396 PuiBackend *self = user_data; |
332 PkNetworkEnum network_state; | 397 |
333 guint elapsed_time; | 398 g_object_get(pk_control, "network-state", &self->network_state, NULL); |
334 guint remaining_time; | |
335 | |
336 g_object_get(pk_control, "network-state", &network_state, NULL); | |
337 g_debug("network state changed: %s", | 399 g_debug("network state changed: %s", |
338 pk_network_enum_to_string(network_state)); | 400 pk_network_enum_to_string(self->network_state)); |
339 if ((self->network_state == PK_NETWORK_ENUM_OFFLINE) && | 401 check_inhibit(self); |
340 (network_state != PK_NETWORK_ENUM_OFFLINE)) { | |
341 /* schedule periodic checks when coming back online */ | |
342 elapsed_time = (g_get_monotonic_time() - self->last_check) / | |
343 G_USEC_PER_SEC; | |
344 /* | |
345 * if more time that the check interval has passed since the | |
346 * last check, schedule a check after a short delay, otherwise | |
347 * wait until the interval has passed | |
348 */ | |
349 remaining_time = (elapsed_time < PUI_CHECK_UPDATES_INTERVAL) ? | |
350 PUI_CHECK_UPDATES_INTERVAL - elapsed_time : | |
351 PUI_STARTUP_DELAY; | |
352 self->periodic_check_id = g_timeout_add_seconds(remaining_time, | |
353 periodic_check, self); | |
354 } else if ((self->network_state != PK_NETWORK_ENUM_OFFLINE) && | |
355 (network_state == PK_NETWORK_ENUM_OFFLINE)) { | |
356 /* cancel periodic checks while offline */ | |
357 if (self->periodic_check_id != 0) { | |
358 g_source_remove(self->periodic_check_id); | |
359 } | |
360 } | |
361 self->network_state = network_state; | |
362 } | 402 } |
363 | 403 |
364 static void | 404 static void |
365 on_updates_changed(PkControl *control, gpointer user_data) | 405 on_updates_changed(PkControl *control, gpointer user_data) |
366 { | 406 { |
368 | 408 |
369 /* | 409 /* |
370 * schedule a check after a short delay so that a rapid succession of | 410 * schedule a check after a short delay so that a rapid succession of |
371 * signals is coalesced | 411 * signals is coalesced |
372 */ | 412 */ |
373 if (self->network_state != PK_NETWORK_ENUM_OFFLINE) { | 413 if (!self->inhibited) { |
374 if (self->periodic_check_id != 0) { | 414 if (self->periodic_check_id != 0) { |
375 g_source_remove(self->periodic_check_id); | 415 g_source_remove(self->periodic_check_id); |
376 } | 416 } |
377 self->periodic_check_id = | 417 self->periodic_check_id = |
378 g_timeout_add_seconds(PUI_STARTUP_DELAY, periodic_check, | 418 g_timeout_add_seconds(PUI_STARTUP_DELAY, periodic_check, |
423 g_signal_connect(self->pk_control, "updates-changed", | 463 g_signal_connect(self->pk_control, "updates-changed", |
424 G_CALLBACK(on_updates_changed), self); | 464 G_CALLBACK(on_updates_changed), self); |
425 /* get notifications when an application restart is required */ | 465 /* get notifications when an application restart is required */ |
426 g_signal_connect(self->pk_control, "restart-schedule", | 466 g_signal_connect(self->pk_control, "restart-schedule", |
427 G_CALLBACK(on_restart_schedule), self); | 467 G_CALLBACK(on_restart_schedule), self); |
428 /* schedule first check after a small delay */ | 468 |
429 self->periodic_check_id = g_timeout_add_seconds(PUI_STARTUP_DELAY, | 469 check_inhibit(self); |
430 periodic_check, self); | |
431 | 470 |
432 return (TRUE); | 471 return (TRUE); |
433 } | 472 } |
434 | 473 |
435 static void | 474 static void |