Branch data Line data Source code
1 : : /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 : : *
3 : : * Copyright © 2019 Endless Mobile, Inc.
4 : : *
5 : : * This library is free software; you can redistribute it and/or
6 : : * modify it under the terms of the GNU Lesser General Public
7 : : * License as published by the Free Software Foundation; either
8 : : * version 2.1 of the License, or (at your option) any later version.
9 : : *
10 : : * This library is distributed in the hope that it will be useful,
11 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 : : * Lesser General Public License for more details.
14 : : *
15 : : * You should have received a copy of the GNU Lesser General Public
16 : : * License along with this library; if not, write to the Free Software
17 : : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 : : *
19 : : * Authors:
20 : : * - Philip Withnall <withnall@endlessm.com>
21 : : */
22 : :
23 : : #include "config.h"
24 : :
25 : : #include <glib.h>
26 : : #include <glib-object.h>
27 : : #include <glib/gi18n-lib.h>
28 : : #include <gio/gio.h>
29 : : #include <libmalcontent/manager.h>
30 : : #include <libmalcontent/session-limits.h>
31 : :
32 : : #include "libmalcontent/session-limits-private.h"
33 : :
34 : :
35 : : /* struct _MctSessionLimits is defined in session-limits-private.h */
36 : :
37 [ + - + - : 6 : G_DEFINE_BOXED_TYPE (MctSessionLimits, mct_session_limits,
+ - ]
38 : : mct_session_limits_ref, mct_session_limits_unref)
39 : :
40 : : /**
41 : : * mct_session_limits_ref:
42 : : * @limits: (transfer none): an #MctSessionLimits
43 : : *
44 : : * Increment the reference count of @limits, and return the same pointer to it.
45 : : *
46 : : * Returns: (transfer full): the same pointer as @limits
47 : : * Since: 0.5.0
48 : : */
49 : : MctSessionLimits *
50 : 4 : mct_session_limits_ref (MctSessionLimits *limits)
51 : : {
52 : 4 : g_return_val_if_fail (limits != NULL, NULL);
53 : 4 : g_return_val_if_fail (limits->ref_count >= 1, NULL);
54 : 4 : g_return_val_if_fail (limits->ref_count <= G_MAXINT - 1, NULL);
55 : :
56 : 4 : limits->ref_count++;
57 : 4 : return limits;
58 : : }
59 : :
60 : : /**
61 : : * mct_session_limits_unref:
62 : : * @limits: (transfer full): an #MctSessionLimits
63 : : *
64 : : * Decrement the reference count of @limits. If the reference count reaches
65 : : * zero, free the @limits and all its resources.
66 : : *
67 : : * Since: 0.5.0
68 : : */
69 : : void
70 : 48 : mct_session_limits_unref (MctSessionLimits *limits)
71 : : {
72 : 48 : g_return_if_fail (limits != NULL);
73 : 48 : g_return_if_fail (limits->ref_count >= 1);
74 : :
75 : 48 : limits->ref_count--;
76 : :
77 [ + + ]: 48 : if (limits->ref_count <= 0)
78 : : {
79 : 44 : g_free (limits);
80 : : }
81 : : }
82 : :
83 : : /**
84 : : * mct_session_limits_get_user_id:
85 : : * @limits: an #MctSessionLimits
86 : : *
87 : : * Get the user ID of the user this #MctSessionLimits is for.
88 : : *
89 : : * Returns: user ID of the relevant user, or `(uid_t) -1` if unknown
90 : : * Since: 0.5.0
91 : : */
92 : : uid_t
93 : 3 : mct_session_limits_get_user_id (MctSessionLimits *limits)
94 : : {
95 : 3 : g_return_val_if_fail (limits != NULL, (uid_t) -1);
96 : 3 : g_return_val_if_fail (limits->ref_count >= 1, (uid_t) -1);
97 : :
98 : 3 : return limits->user_id;
99 : : }
100 : :
101 : : /**
102 : : * mct_session_limits_is_enabled:
103 : : * @limits: an #MctSessionLimits
104 : : *
105 : : * Check whether any session limits are enabled and are going to impose at least
106 : : * one restriction on the user. This gives a high level view of whether session
107 : : * limit parental controls are ‘enabled’ for the given user.
108 : : *
109 : : * This function is equivalent to the value returned by the
110 : : * `time_limit_enabled_out` argument of
111 : : * mct_session_limits_check_time_remaining().
112 : : *
113 : : * Returns: %TRUE if the session limits object contains at least one restrictive
114 : : * session limit, %FALSE if there are no limits in place
115 : : * Since: 0.7.0
116 : : */
117 : : gboolean
118 : 3 : mct_session_limits_is_enabled (MctSessionLimits *limits)
119 : : {
120 : 3 : g_return_val_if_fail (limits != NULL, FALSE);
121 : 3 : g_return_val_if_fail (limits->ref_count >= 1, FALSE);
122 : :
123 : 3 : return (limits->limit_type != MCT_SESSION_LIMITS_TYPE_NONE);
124 : : }
125 : :
126 : : /**
127 : : * mct_session_limits_check_time_remaining:
128 : : * @limits: an #MctSessionLimits
129 : : * @now_usecs: current time as microseconds since the Unix epoch (UTC),
130 : : * typically queried using g_get_real_time()
131 : : * @time_remaining_secs_out: (out) (optional): return location for the number
132 : : * of seconds remaining before the user’s session has to end, if limits are
133 : : * in force
134 : : * @time_limit_enabled_out: (out) (optional): return location for whether time
135 : : * limits are enabled for this user
136 : : *
137 : : * Check whether the user has time remaining in which they are allowed to use
138 : : * the computer, assuming that @now_usecs is the current time, and applying the
139 : : * session limit policy from @limits to it.
140 : : *
141 : : * This will return whether the user is allowed to use the computer now; further
142 : : * information about the policy and remaining time is provided in
143 : : * @time_remaining_secs_out and @time_limit_enabled_out.
144 : : *
145 : : * Returns: %TRUE if the user this @limits corresponds to is allowed to be in
146 : : * an active session at the given time; %FALSE otherwise
147 : : * Since: 0.5.0
148 : : */
149 : : gboolean
150 : 102 : mct_session_limits_check_time_remaining (MctSessionLimits *limits,
151 : : guint64 now_usecs,
152 : : guint64 *time_remaining_secs_out,
153 : : gboolean *time_limit_enabled_out)
154 : : {
155 : : guint64 time_remaining_secs;
156 : : gboolean time_limit_enabled;
157 : : gboolean user_allowed_now;
158 : 102 : g_autoptr(GDateTime) now_dt = NULL;
159 : : guint64 now_time_of_day_secs;
160 : :
161 : 102 : g_return_val_if_fail (limits != NULL, FALSE);
162 : 102 : g_return_val_if_fail (limits->ref_count >= 1, FALSE);
163 : :
164 : : /* Helper calculations. */
165 : 102 : now_dt = g_date_time_new_from_unix_utc (now_usecs / G_USEC_PER_SEC);
166 [ + + ]: 102 : if (now_dt == NULL)
167 : : {
168 : 2 : time_remaining_secs = 0;
169 : 2 : time_limit_enabled = TRUE;
170 : 2 : user_allowed_now = FALSE;
171 : 2 : goto out;
172 : : }
173 : :
174 : 100 : now_time_of_day_secs = ((g_date_time_get_hour (now_dt) * 60 +
175 : 100 : g_date_time_get_minute (now_dt)) * 60 +
176 : 100 : g_date_time_get_second (now_dt));
177 : :
178 : : /* Work out the limits. */
179 [ + + ]: 100 : switch (limits->limit_type)
180 : : {
181 : 60 : case MCT_SESSION_LIMITS_TYPE_DAILY_SCHEDULE:
182 [ + + ]: 96 : user_allowed_now = (now_time_of_day_secs >= limits->daily_start_time &&
183 [ + + ]: 36 : now_time_of_day_secs < limits->daily_end_time);
184 [ + + ]: 60 : time_remaining_secs = user_allowed_now ? (limits->daily_end_time - now_time_of_day_secs) : 0;
185 : 60 : time_limit_enabled = TRUE;
186 : :
187 : 60 : g_debug ("%s: Daily schedule limit allowed in %u–%u (now is %"
188 : : G_GUINT64_FORMAT "); %" G_GUINT64_FORMAT " seconds remaining",
189 : : G_STRFUNC, limits->daily_start_time, limits->daily_end_time,
190 : : now_time_of_day_secs, time_remaining_secs);
191 : :
192 : 60 : break;
193 : 40 : case MCT_SESSION_LIMITS_TYPE_NONE:
194 : : default:
195 : 40 : user_allowed_now = TRUE;
196 : 40 : time_remaining_secs = G_MAXUINT64;
197 : 40 : time_limit_enabled = FALSE;
198 : :
199 : 40 : g_debug ("%s: No limit enabled", G_STRFUNC);
200 : :
201 : 40 : break;
202 : : }
203 : :
204 : 102 : out:
205 : : /* Postconditions. */
206 : 102 : g_assert (!user_allowed_now || time_remaining_secs > 0);
207 : 102 : g_assert (user_allowed_now || time_remaining_secs == 0);
208 : 102 : g_assert (time_limit_enabled || time_remaining_secs == G_MAXUINT64);
209 : :
210 : : /* Output. */
211 [ + + ]: 102 : if (time_remaining_secs_out != NULL)
212 : 8 : *time_remaining_secs_out = time_remaining_secs;
213 [ + + ]: 102 : if (time_limit_enabled_out != NULL)
214 : 8 : *time_limit_enabled_out = time_limit_enabled;
215 : :
216 : 102 : return user_allowed_now;
217 : : }
218 : :
219 : : /**
220 : : * mct_session_limits_serialize:
221 : : * @limits: an #MctSessionLimits
222 : : *
223 : : * Build a #GVariant which contains the session limits from @limits, in an
224 : : * opaque variant format. This format may change in future, but
225 : : * mct_session_limits_deserialize() is guaranteed to always be able to load any
226 : : * variant produced by the current or any previous version of
227 : : * mct_session_limits_serialize().
228 : : *
229 : : * Returns: (transfer floating): a new, floating #GVariant containing the
230 : : * session limits
231 : : * Since: 0.7.0
232 : : */
233 : : GVariant *
234 : 8 : mct_session_limits_serialize (MctSessionLimits *limits)
235 : : {
236 : 16 : g_auto(GVariantBuilder) builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{sv}"));
237 : 8 : g_autoptr(GVariant) limit_variant = NULL;
238 : : const gchar *limit_property_name;
239 : :
240 : 8 : g_return_val_if_fail (limits != NULL, NULL);
241 : 8 : g_return_val_if_fail (limits->ref_count >= 1, NULL);
242 : :
243 : : /* The serialisation format is exactly the
244 : : * `com.endlessm.ParentalControls.SessionLimits` D-Bus interface. */
245 [ + + - ]: 8 : switch (limits->limit_type)
246 : : {
247 : 4 : case MCT_SESSION_LIMITS_TYPE_DAILY_SCHEDULE:
248 : 4 : limit_variant = g_variant_new ("(uu)",
249 : : limits->daily_start_time,
250 : : limits->daily_end_time);
251 : 4 : limit_property_name = "DailySchedule";
252 : 4 : break;
253 : 4 : case MCT_SESSION_LIMITS_TYPE_NONE:
254 : 4 : limit_variant = NULL;
255 : 4 : limit_property_name = NULL;
256 : 4 : break;
257 : 0 : default:
258 : : g_assert_not_reached ();
259 : : }
260 : :
261 [ + + ]: 8 : if (limit_property_name != NULL)
262 : : {
263 : 4 : g_variant_builder_add (&builder, "{sv}", limit_property_name,
264 : 4 : g_steal_pointer (&limit_variant));
265 : : }
266 : :
267 : 8 : g_variant_builder_add (&builder, "{sv}", "LimitType",
268 : 8 : g_variant_new_uint32 (limits->limit_type));
269 : :
270 : 8 : return g_variant_builder_end (&builder);
271 : : }
272 : :
273 : : /**
274 : : * mct_session_limits_deserialize:
275 : : * @variant: a serialized session limits variant
276 : : * @user_id: the ID of the user the session limits relate to
277 : : * @error: return location for a #GError, or %NULL
278 : : *
279 : : * Deserialize a set of session limits previously serialized with
280 : : * mct_session_limits_serialize(). This function guarantees to be able to
281 : : * deserialize any serialized form from this version or older versions of
282 : : * libmalcontent.
283 : : *
284 : : * If deserialization fails, %MCT_MANAGER_ERROR_INVALID_DATA will be returned.
285 : : *
286 : : * Returns: (transfer full): deserialized session limits
287 : : * Since: 0.7.0
288 : : */
289 : : MctSessionLimits *
290 : 21 : mct_session_limits_deserialize (GVariant *variant,
291 : : uid_t user_id,
292 : : GError **error)
293 : : {
294 : 21 : g_autoptr(MctSessionLimits) session_limits = NULL;
295 : : guint32 limit_type;
296 : : guint32 daily_start_time, daily_end_time;
297 : :
298 : 21 : g_return_val_if_fail (variant != NULL, NULL);
299 : 21 : g_return_val_if_fail (error == NULL || *error == NULL, NULL);
300 : :
301 : : /* Check the overall type. */
302 [ + + ]: 21 : if (!g_variant_is_of_type (variant, G_VARIANT_TYPE ("a{sv}")))
303 : : {
304 : 4 : g_set_error (error, MCT_MANAGER_ERROR,
305 : : MCT_MANAGER_ERROR_INVALID_DATA,
306 : : _("Session limit for user %u was in an unrecognized format"),
307 : : (guint) user_id);
308 : 4 : return NULL;
309 : : }
310 : :
311 : : /* Extract the properties we care about. The default values here should be
312 : : * kept in sync with those in the `com.endlessm.ParentalControls.SessionLimits`
313 : : * D-Bus interface. */
314 [ + + ]: 17 : if (!g_variant_lookup (variant, "LimitType", "u",
315 : : &limit_type))
316 : : {
317 : : /* Default value. */
318 : 8 : limit_type = MCT_SESSION_LIMITS_TYPE_NONE;
319 : : }
320 : :
321 : : /* Check that the limit type is something we support. */
322 : : G_STATIC_ASSERT (sizeof (limit_type) >= sizeof (MctSessionLimitsType));
323 : :
324 [ + + ]: 17 : if ((guint) limit_type > MCT_SESSION_LIMITS_TYPE_DAILY_SCHEDULE)
325 : : {
326 : 2 : g_set_error (error, MCT_MANAGER_ERROR,
327 : : MCT_MANAGER_ERROR_INVALID_DATA,
328 : : _("Session limit for user %u has an unrecognized type ‘%u’"),
329 : : (guint) user_id, limit_type);
330 : 2 : return NULL;
331 : : }
332 : :
333 [ + + ]: 15 : if (!g_variant_lookup (variant, "DailySchedule", "(uu)",
334 : : &daily_start_time, &daily_end_time))
335 : : {
336 : : /* Default value. */
337 : 4 : daily_start_time = 0;
338 : 4 : daily_end_time = 24 * 60 * 60;
339 : : }
340 : :
341 [ + + ]: 15 : if (daily_start_time >= daily_end_time ||
342 [ + + ]: 13 : daily_end_time > 24 * 60 * 60)
343 : : {
344 : 4 : g_set_error (error, MCT_MANAGER_ERROR,
345 : : MCT_MANAGER_ERROR_INVALID_DATA,
346 : : _("Session limit for user %u has invalid daily schedule %u–%u"),
347 : : (guint) user_id, daily_start_time, daily_end_time);
348 : 4 : return NULL;
349 : : }
350 : :
351 : : /* Success. Create an #MctSessionLimits object to contain the results. */
352 : 11 : session_limits = g_new0 (MctSessionLimits, 1);
353 : 11 : session_limits->ref_count = 1;
354 : 11 : session_limits->user_id = user_id;
355 : 11 : session_limits->limit_type = limit_type;
356 : 11 : session_limits->daily_start_time = daily_start_time;
357 : 11 : session_limits->daily_end_time = daily_end_time;
358 : :
359 : 11 : return g_steal_pointer (&session_limits);
360 : : }
361 : :
362 : : /*
363 : : * Actual implementation of #MctSessionLimitsBuilder.
364 : : *
365 : : * All members are %NULL if un-initialised, cleared, or ended.
366 : : */
367 : : typedef struct
368 : : {
369 : : MctSessionLimitsType limit_type;
370 : :
371 : : /* Which member is used is determined by @limit_type: */
372 : : union
373 : : {
374 : : struct
375 : : {
376 : : guint start_time; /* seconds since midnight */
377 : : guint end_time; /* seconds since midnight */
378 : : } daily_schedule;
379 : : };
380 : :
381 : : /*< private >*/
382 : : gpointer padding[10];
383 : : } MctSessionLimitsBuilderReal;
384 : :
385 : : G_STATIC_ASSERT (sizeof (MctSessionLimitsBuilderReal) ==
386 : : sizeof (MctSessionLimitsBuilder));
387 : : G_STATIC_ASSERT (__alignof__ (MctSessionLimitsBuilderReal) ==
388 : : __alignof__ (MctSessionLimitsBuilder));
389 : :
390 [ + - + - : 6 : G_DEFINE_BOXED_TYPE (MctSessionLimitsBuilder, mct_session_limits_builder,
+ - ]
391 : : mct_session_limits_builder_copy, mct_session_limits_builder_free)
392 : :
393 : : /**
394 : : * mct_session_limits_builder_init:
395 : : * @builder: an uninitialised #MctSessionLimitsBuilder
396 : : *
397 : : * Initialise the given @builder so it can be used to construct a new
398 : : * #MctSessionLimits. @builder must have been allocated on the stack, and must
399 : : * not already be initialised.
400 : : *
401 : : * Construct the #MctSessionLimits by calling methods on @builder, followed by
402 : : * mct_session_limits_builder_end(). To abort construction, use
403 : : * mct_session_limits_builder_clear().
404 : : *
405 : : * Since: 0.5.0
406 : : */
407 : : void
408 : 22 : mct_session_limits_builder_init (MctSessionLimitsBuilder *builder)
409 : : {
410 : 22 : MctSessionLimitsBuilder local_builder = MCT_SESSION_LIMITS_BUILDER_INIT ();
411 : 22 : MctSessionLimitsBuilderReal *_builder = (MctSessionLimitsBuilderReal *) builder;
412 : :
413 : 22 : g_return_if_fail (_builder != NULL);
414 : 22 : g_return_if_fail (_builder->limit_type == MCT_SESSION_LIMITS_TYPE_NONE);
415 : :
416 : 22 : memcpy (builder, &local_builder, sizeof (local_builder));
417 : : }
418 : :
419 : : /**
420 : : * mct_session_limits_builder_clear:
421 : : * @builder: an #MctSessionLimitsBuilder
422 : : *
423 : : * Clear @builder, freeing any internal state in it. This will not free the
424 : : * top-level storage for @builder itself, which is assumed to be allocated on
425 : : * the stack.
426 : : *
427 : : * If called on an already-cleared #MctSessionLimitsBuilder, this function is
428 : : * idempotent.
429 : : *
430 : : * Since: 0.5.0
431 : : */
432 : : void
433 : 76 : mct_session_limits_builder_clear (MctSessionLimitsBuilder *builder)
434 : : {
435 : 76 : MctSessionLimitsBuilderReal *_builder = (MctSessionLimitsBuilderReal *) builder;
436 : :
437 : 76 : g_return_if_fail (_builder != NULL);
438 : :
439 : : /* Nothing to free here for now. */
440 : 76 : _builder->limit_type = MCT_SESSION_LIMITS_TYPE_NONE;
441 : : }
442 : :
443 : : /**
444 : : * mct_session_limits_builder_new:
445 : : *
446 : : * Construct a new #MctSessionLimitsBuilder on the heap. This is intended for
447 : : * language bindings. The returned builder must eventually be freed with
448 : : * mct_session_limits_builder_free(), but can be cleared zero or more times with
449 : : * mct_session_limits_builder_clear() first.
450 : : *
451 : : * Returns: (transfer full): a new heap-allocated #MctSessionLimitsBuilder
452 : : * Since: 0.5.0
453 : : */
454 : : MctSessionLimitsBuilder *
455 : 16 : mct_session_limits_builder_new (void)
456 : : {
457 : 16 : g_autoptr(MctSessionLimitsBuilder) builder = NULL;
458 : :
459 : 16 : builder = g_new0 (MctSessionLimitsBuilder, 1);
460 : 16 : mct_session_limits_builder_init (builder);
461 : :
462 : 16 : return g_steal_pointer (&builder);
463 : : }
464 : :
465 : : /**
466 : : * mct_session_limits_builder_copy:
467 : : * @builder: an #MctSessionLimitsBuilder
468 : : *
469 : : * Copy the given @builder to a newly-allocated #MctSessionLimitsBuilder on the
470 : : * heap. This is safe to use with cleared, stack-allocated
471 : : * #MctSessionLimitsBuilders.
472 : : *
473 : : * Returns: (transfer full): a copy of @builder
474 : : * Since: 0.5.0
475 : : */
476 : : MctSessionLimitsBuilder *
477 : 4 : mct_session_limits_builder_copy (MctSessionLimitsBuilder *builder)
478 : : {
479 : 4 : MctSessionLimitsBuilderReal *_builder = (MctSessionLimitsBuilderReal *) builder;
480 : 4 : g_autoptr(MctSessionLimitsBuilder) copy = NULL;
481 : : MctSessionLimitsBuilderReal *_copy;
482 : :
483 : 4 : g_return_val_if_fail (builder != NULL, NULL);
484 : :
485 : 4 : copy = mct_session_limits_builder_new ();
486 : 4 : _copy = (MctSessionLimitsBuilderReal *) copy;
487 : :
488 : 4 : mct_session_limits_builder_clear (copy);
489 : 4 : _copy->limit_type = _builder->limit_type;
490 : :
491 [ + + ]: 4 : switch (_builder->limit_type)
492 : : {
493 : 2 : case MCT_SESSION_LIMITS_TYPE_DAILY_SCHEDULE:
494 : 2 : _copy->daily_schedule.start_time = _builder->daily_schedule.start_time;
495 : 2 : _copy->daily_schedule.end_time = _builder->daily_schedule.end_time;
496 : 2 : break;
497 : 2 : case MCT_SESSION_LIMITS_TYPE_NONE:
498 : : default:
499 : 2 : break;
500 : : }
501 : :
502 : 4 : return g_steal_pointer (©);
503 : : }
504 : :
505 : : /**
506 : : * mct_session_limits_builder_free:
507 : : * @builder: a heap-allocated #MctSessionLimitsBuilder
508 : : *
509 : : * Free an #MctSessionLimitsBuilder originally allocated using
510 : : * mct_session_limits_builder_new(). This must not be called on stack-allocated
511 : : * builders initialised using mct_session_limits_builder_init().
512 : : *
513 : : * Since: 0.5.0
514 : : */
515 : : void
516 : 16 : mct_session_limits_builder_free (MctSessionLimitsBuilder *builder)
517 : : {
518 : 16 : g_return_if_fail (builder != NULL);
519 : :
520 : 16 : mct_session_limits_builder_clear (builder);
521 : 16 : g_free (builder);
522 : : }
523 : :
524 : : /**
525 : : * mct_session_limits_builder_end:
526 : : * @builder: an initialised #MctSessionLimitsBuilder
527 : : *
528 : : * Finish constructing an #MctSessionLimits with the given @builder, and return
529 : : * it. The #MctSessionLimitsBuilder will be cleared as if
530 : : * mct_session_limits_builder_clear() had been called.
531 : : *
532 : : * Returns: (transfer full): a newly constructed #MctSessionLimits
533 : : * Since: 0.5.0
534 : : */
535 : : MctSessionLimits *
536 : 33 : mct_session_limits_builder_end (MctSessionLimitsBuilder *builder)
537 : : {
538 : 33 : MctSessionLimitsBuilderReal *_builder = (MctSessionLimitsBuilderReal *) builder;
539 : 33 : g_autoptr(MctSessionLimits) session_limits = NULL;
540 : :
541 : 33 : g_return_val_if_fail (_builder != NULL, NULL);
542 : :
543 : : /* Build the #MctSessionLimits. */
544 : 33 : session_limits = g_new0 (MctSessionLimits, 1);
545 : 33 : session_limits->ref_count = 1;
546 : 33 : session_limits->user_id = -1;
547 : 33 : session_limits->limit_type = _builder->limit_type;
548 : :
549 [ + + ]: 33 : switch (_builder->limit_type)
550 : : {
551 : 16 : case MCT_SESSION_LIMITS_TYPE_DAILY_SCHEDULE:
552 : 16 : session_limits->daily_start_time = _builder->daily_schedule.start_time;
553 : 16 : session_limits->daily_end_time = _builder->daily_schedule.end_time;
554 : 16 : break;
555 : 17 : case MCT_SESSION_LIMITS_TYPE_NONE:
556 : : default:
557 : : /* Defaults: */
558 : 17 : session_limits->daily_start_time = 0;
559 : 17 : session_limits->daily_end_time = 24 * 60 * 60;
560 : 17 : break;
561 : : }
562 : :
563 : 33 : mct_session_limits_builder_clear (builder);
564 : :
565 : 33 : return g_steal_pointer (&session_limits);
566 : : }
567 : :
568 : : /**
569 : : * mct_session_limits_builder_set_none:
570 : : * @builder: an initialised #MctSessionLimitsBuilder
571 : : *
572 : : * Unset any session limits currently set in the @builder.
573 : : *
574 : : * Since: 0.5.0
575 : : */
576 : : void
577 : 2 : mct_session_limits_builder_set_none (MctSessionLimitsBuilder *builder)
578 : : {
579 : 2 : MctSessionLimitsBuilderReal *_builder = (MctSessionLimitsBuilderReal *) builder;
580 : :
581 : 2 : g_return_if_fail (_builder != NULL);
582 : :
583 : : /* This will need to free other limit types’ data first in future. */
584 : 2 : _builder->limit_type = MCT_SESSION_LIMITS_TYPE_NONE;
585 : : }
586 : :
587 : : /**
588 : : * mct_session_limits_builder_set_daily_schedule:
589 : : * @builder: an initialised #MctSessionLimitsBuilder
590 : : * @start_time_secs: number of seconds since midnight when the user’s session
591 : : * can first start
592 : : * @end_time_secs: number of seconds since midnight when the user’s session can
593 : : * last end
594 : : *
595 : : * Set the session limits in @builder to be a daily schedule, where sessions are
596 : : * allowed between @start_time_secs and @end_time_secs every day.
597 : : * @start_time_secs and @end_time_secs are given as offsets from the start of
598 : : * the day, in seconds. @end_time_secs must be greater than @start_time_secs.
599 : : * @end_time_secs must be at most `24 * 60 * 60`.
600 : : *
601 : : * This will overwrite any other session limits.
602 : : *
603 : : * Since: 0.5.0
604 : : */
605 : : void
606 : 20 : mct_session_limits_builder_set_daily_schedule (MctSessionLimitsBuilder *builder,
607 : : guint start_time_secs,
608 : : guint end_time_secs)
609 : : {
610 : 20 : MctSessionLimitsBuilderReal *_builder = (MctSessionLimitsBuilderReal *) builder;
611 : :
612 : 20 : g_return_if_fail (_builder != NULL);
613 : 20 : g_return_if_fail (start_time_secs < end_time_secs);
614 : 20 : g_return_if_fail (end_time_secs <= 24 * 60 * 60);
615 : :
616 : : /* This will need to free other limit types’ data first in future. */
617 : 20 : _builder->limit_type = MCT_SESSION_LIMITS_TYPE_DAILY_SCHEDULE;
618 : 20 : _builder->daily_schedule.start_time = start_time_secs;
619 : 20 : _builder->daily_schedule.end_time = end_time_secs;
620 : : }
|