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