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