LCOV - code coverage report
Current view: top level - malcontent-control - screen-time-statistics-row.c (source / functions) Coverage Total Hit
Test: 2 coverage DB files Lines: 0.0 % 169 0
Test Date: 2025-11-20 19:57:30 Functions: 0.0 % 20 0
Branches: 0.0 % 62 0

             Branch data     Line data    Source code
       1                 :             : /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
       2                 :             :  *
       3                 :             :  * Copyright 2025 GNOME Foundation, Inc.
       4                 :             :  *
       5                 :             :  * SPDX-License-Identifier: GPL-2.0-or-later
       6                 :             :  *
       7                 :             :  * This program is free software; you can redistribute it and/or modify
       8                 :             :  * it under the terms of the GNU General Public License as published by
       9                 :             :  * the Free Software Foundation; either version 2 of the License, or
      10                 :             :  * (at your option) any later version.
      11                 :             :  *
      12                 :             :  * This program 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
      15                 :             :  * GNU General Public License for more details.
      16                 :             :  *
      17                 :             :  * You should have received a copy of the GNU General Public License
      18                 :             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      19                 :             :  *
      20                 :             :  * Authors:
      21                 :             :  *  - Ignacy Kuchciński <ignacykuchcinski@gnome.org>
      22                 :             :  */
      23                 :             : 
      24                 :             : #include "config.h"
      25                 :             : 
      26                 :             : #include <glib/gi18n.h>
      27                 :             : #include <stdint.h>
      28                 :             : 
      29                 :             : #include "screen-time-statistics-row.h"
      30                 :             : 
      31                 :             : /**
      32                 :             :  * MctScreenTimeStatisticsRow:
      33                 :             :  *
      34                 :             :  * A widget which shows screen time bar chart for screen time usage
      35                 :             :  * records for the selected user.
      36                 :             :  *
      37                 :             :  * Since: 0.14.0
      38                 :             :  */
      39                 :             : struct _MctScreenTimeStatisticsRow
      40                 :             : {
      41                 :             :   CcScreenTimeStatisticsRow parent;
      42                 :             : 
      43                 :             :   unsigned long usage_changed_id;
      44                 :             : 
      45                 :             :   GDBusConnection *connection; /* (owned) */
      46                 :             :   uid_t uid;
      47                 :             : };
      48                 :             : 
      49   [ #  #  #  #  :           0 : G_DEFINE_TYPE (MctScreenTimeStatisticsRow, mct_screen_time_statistics_row, CC_TYPE_SCREEN_TIME_STATISTICS_ROW)
                   #  # ]
      50                 :             : 
      51                 :             : typedef enum
      52                 :             : {
      53                 :             :   PROP_CONNECTION = 1,
      54                 :             :   PROP_UID,
      55                 :             : } MctScreenTimeStatisticsRowProperty;
      56                 :             : 
      57                 :             : static GParamSpec *properties[PROP_UID + 1];
      58                 :             : 
      59                 :             : static void
      60                 :           0 : mct_screen_time_statistics_row_get_property (GObject      *object,
      61                 :             :                                              unsigned int  property_id,
      62                 :             :                                              GValue       *value,
      63                 :             :                                              GParamSpec   *spec)
      64                 :             : {
      65                 :           0 :   MctScreenTimeStatisticsRow *self = MCT_SCREEN_TIME_STATISTICS_ROW (object);
      66                 :             : 
      67      [ #  #  # ]:           0 :   switch ((MctScreenTimeStatisticsRowProperty) property_id)
      68                 :             :   {
      69                 :           0 :     case PROP_CONNECTION:
      70                 :           0 :       g_value_set_object (value, self->connection);
      71                 :           0 :       break;
      72                 :             : 
      73                 :           0 :     case PROP_UID:
      74                 :           0 :       g_value_set_uint (value, self->uid);
      75                 :           0 :       break;
      76                 :             : 
      77                 :           0 :     default:
      78                 :           0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
      79                 :           0 :       break;
      80                 :             :   }
      81                 :           0 : }
      82                 :             : 
      83                 :             : static void
      84                 :           0 : mct_screen_time_statistics_row_set_property (GObject      *object,
      85                 :             :                                              unsigned int  property_id,
      86                 :             :                                              const GValue *value,
      87                 :             :                                              GParamSpec   *spec)
      88                 :             : {
      89                 :           0 :   MctScreenTimeStatisticsRow *self = MCT_SCREEN_TIME_STATISTICS_ROW (object);
      90                 :             : 
      91      [ #  #  # ]:           0 :   switch ((MctScreenTimeStatisticsRowProperty) property_id)
      92                 :             :   {
      93                 :           0 :     case PROP_CONNECTION:
      94                 :             :       /* Construct-only. May not be %NULL. */
      95                 :           0 :       g_assert (self->connection == NULL);
      96                 :           0 :       self->connection = g_value_dup_object (value);
      97                 :           0 :       g_assert (self->connection != NULL);
      98                 :           0 :       break;
      99                 :             : 
     100                 :           0 :     case PROP_UID:
     101                 :             :       /* Construct-only. */
     102                 :           0 :       g_assert (self->uid == 0);
     103                 :           0 :       self->uid = g_value_get_uint (value);
     104                 :           0 :       g_assert (self->uid != 0);
     105                 :           0 :       break;
     106                 :             : 
     107                 :           0 :     default:
     108                 :           0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
     109                 :           0 :       break;
     110                 :             :   }
     111                 :           0 : }
     112                 :             : 
     113                 :             : static void
     114                 :           0 : mct_screen_time_statistics_row_constructed (GObject *object)
     115                 :             : {
     116                 :           0 :   MctScreenTimeStatisticsRow *self = MCT_SCREEN_TIME_STATISTICS_ROW (object);
     117                 :             : 
     118                 :           0 :   g_assert (self->connection != NULL);
     119                 :           0 :   g_assert (self->uid != 0);
     120                 :             : 
     121                 :           0 :   G_OBJECT_CLASS (mct_screen_time_statistics_row_parent_class)->constructed (object);
     122                 :           0 : }
     123                 :             : 
     124                 :             : static void
     125                 :           0 : mct_screen_time_statistics_row_dispose (GObject *object)
     126                 :             : {
     127                 :           0 :   MctScreenTimeStatisticsRow *self = MCT_SCREEN_TIME_STATISTICS_ROW (object);
     128                 :             : 
     129   [ #  #  #  # ]:           0 :   if (self->connection != NULL && self->usage_changed_id != 0)
     130                 :             :   {
     131                 :           0 :     g_dbus_connection_signal_unsubscribe (self->connection, self->usage_changed_id);
     132                 :           0 :     self->usage_changed_id = 0;
     133                 :             :   }
     134                 :             : 
     135         [ #  # ]:           0 :   g_clear_object (&self->connection);
     136                 :             : 
     137                 :           0 :   G_OBJECT_CLASS (mct_screen_time_statistics_row_parent_class)->dispose (object);
     138                 :           0 : }
     139                 :             : 
     140                 :             : typedef struct
     141                 :             : {
     142                 :             :   GDate *start_date;
     143                 :             :   size_t n_days;
     144                 :             :   double *screen_time_per_day;
     145                 :             : } LoadDataData;
     146                 :             : 
     147                 :             : static void
     148                 :           0 : load_data_data_free (LoadDataData *data)
     149                 :             : {
     150                 :           0 :   g_date_free (data->start_date);
     151                 :           0 :   g_free (data->screen_time_per_day);
     152                 :           0 :   g_free (data);
     153                 :           0 : }
     154                 :             : 
     155         [ #  # ]:           0 : G_DEFINE_AUTOPTR_CLEANUP_FUNC (LoadDataData, load_data_data_free)
     156                 :             : 
     157                 :             : /**
     158                 :             :  * load_data_data_new:
     159                 :             :  * @start_date: (transfer none): an initialized [struct@GLib.Date]
     160                 :             :  * @n_days: number of days
     161                 :             :  * @screen_time_per_day: (transfer full): screen time per day
     162                 :             :  */
     163                 :             : static LoadDataData *
     164                 :           0 : load_data_data_new (GDate  *start_date,
     165                 :             :                     size_t  n_days,
     166                 :             :                     double *screen_time_per_day)
     167                 :             : {
     168                 :           0 :   g_autoptr(LoadDataData) data = g_new0 (LoadDataData, 1);
     169                 :             : 
     170                 :           0 :   data->start_date = g_date_copy (start_date);
     171                 :           0 :   data->n_days = n_days;
     172                 :           0 :   data->screen_time_per_day = screen_time_per_day;
     173                 :             : 
     174                 :           0 :   return g_steal_pointer (&data);
     175                 :             : }
     176                 :             : 
     177                 :             : static void
     178                 :             : query_usage_cb (GObject      *object,
     179                 :             :                 GAsyncResult *result,
     180                 :             :                 void         *user_data);
     181                 :             : static void
     182                 :             : usage_changed_cb (GDBusConnection *connection,
     183                 :             :                   const char      *sender_name,
     184                 :             :                   const char      *object_path,
     185                 :             :                   const char      *interface_name,
     186                 :             :                   const char      *signal_name,
     187                 :             :                   GVariant        *parameters,
     188                 :             :                   void            *user_data);
     189                 :             : 
     190                 :             : static void
     191                 :           0 : mct_screen_time_statistics_row_load_data_async (CcScreenTimeStatisticsRow *screen_time_statistics_row,
     192                 :             :                                                 GCancellable              *cancellable,
     193                 :             :                                                 GAsyncReadyCallback        callback,
     194                 :             :                                                 void                      *user_data)
     195                 :             : {
     196                 :           0 :   MctScreenTimeStatisticsRow *self = MCT_SCREEN_TIME_STATISTICS_ROW (screen_time_statistics_row);
     197                 :           0 :   g_autoptr(GTask) task = NULL;
     198                 :             : 
     199                 :           0 :   task = g_task_new (self, cancellable, callback, user_data);
     200         [ #  # ]:           0 :   g_task_set_source_tag (task, mct_screen_time_statistics_row_load_data_async);
     201                 :             : 
     202                 :             :   /* Load and parse the screen time usage periods of the child account using
     203                 :             :    * the org.freedesktop.MalcontentTimer1.Parent malcontent-timerd interface.
     204                 :             :    * See `timeLimitsManager.js` in gnome-shell for the code which records the
     205                 :             :    * usage using org.freedesktop.MalcontentTimer1.Child interface. */
     206                 :           0 :   g_dbus_connection_call (self->connection,
     207                 :             :                           "org.freedesktop.MalcontentTimer1",
     208                 :             :                           "/org/freedesktop/MalcontentTimer1",
     209                 :             :                           "org.freedesktop.MalcontentTimer1.Parent",
     210                 :             :                           "QueryUsage",
     211                 :             :                           g_variant_new ("(uss)",
     212                 :             :                                          self->uid,
     213                 :             :                                          "login-session",
     214                 :             :                                          ""),
     215                 :             :                           (const GVariantType *) "(a(tt))",
     216                 :             :                           G_DBUS_CALL_FLAGS_NONE,
     217                 :             :                           -1,
     218                 :             :                           cancellable,
     219                 :             :                           query_usage_cb,
     220                 :             :                           g_steal_pointer (&task));
     221                 :             : 
     222                 :             :   /* Start watching for screen time usage changes coming from the daemon. */
     223                 :           0 :   self->usage_changed_id =
     224                 :           0 :     g_dbus_connection_signal_subscribe (self->connection,
     225                 :             :                                         "org.freedesktop.MalcontentTimer1",
     226                 :             :                                         "org.freedesktop.MalcontentTimer1.Parent",
     227                 :             :                                         "UsageChanged",
     228                 :             :                                         "/org/freedesktop/MalcontentTimer1",
     229                 :             :                                         NULL,
     230                 :             :                                         G_DBUS_SIGNAL_FLAGS_NONE,
     231                 :             :                                         usage_changed_cb,
     232                 :             :                                         self,
     233                 :             :                                         NULL);
     234                 :           0 : }
     235                 :             : 
     236                 :             : static void allocate_duration_to_days (const GDate *model_start_date,
     237                 :             :                                        GArray      *model_screen_time_per_day,
     238                 :             :                                        uint64_t     start_wall_time_secs,
     239                 :             :                                        uint64_t     duration_secs);
     240                 :             : 
     241                 :             : static void
     242                 :           0 : query_usage_cb (GObject      *object,
     243                 :             :                 GAsyncResult *result,
     244                 :             :                 void         *user_data)
     245                 :             : {
     246                 :           0 :   GDBusConnection *connection = G_DBUS_CONNECTION (object);
     247         [ #  # ]:           0 :   g_autoptr(GTask) task = G_TASK (g_steal_pointer (&user_data));
     248                 :             :   GDate new_model_start_date;
     249                 :             :   size_t new_model_n_days;
     250         [ #  # ]:           0 :   g_autoptr(GArray) new_model_screen_time_per_day = NULL;  /* (element-type double) */
     251         [ #  # ]:           0 :   g_autoptr(GVariant) result_variant = NULL;
     252         [ #  # ]:           0 :   g_autoptr(GError) local_error = NULL;
     253         [ #  # ]:           0 :   g_autoptr(GVariantIter) entries_iter = NULL;
     254                 :             :   uint64_t start_wall_time_secs, end_wall_time_secs;
     255                 :             : 
     256                 :           0 :   g_date_clear (&new_model_start_date, 1);
     257                 :             : 
     258                 :           0 :   result_variant = g_dbus_connection_call_finish (connection, result, &local_error);
     259                 :             : 
     260         [ #  # ]:           0 :   if (result_variant == NULL)
     261                 :             :     {
     262                 :           0 :       g_task_return_error (task, g_steal_pointer (&local_error));
     263                 :           0 :       return;
     264                 :             :     }
     265                 :             : 
     266                 :           0 :   g_variant_get (result_variant, "(a(tt))", &entries_iter);
     267         [ #  # ]:           0 :   while (g_variant_iter_loop (entries_iter, "(tt)", &start_wall_time_secs, &end_wall_time_secs))
     268                 :             :     {
     269                 :             :       /* Set up the model if this is the first iteration */
     270         [ #  # ]:           0 :       if (!g_date_valid (&new_model_start_date))
     271                 :             :         {
     272                 :           0 :           g_date_set_time_t (&new_model_start_date, start_wall_time_secs);
     273                 :           0 :           new_model_screen_time_per_day = g_array_new (FALSE, TRUE, sizeof (double));
     274                 :             :         }
     275                 :             : 
     276                 :             :       /* Interpret the data */
     277                 :           0 :       uint64_t duration_secs = end_wall_time_secs - start_wall_time_secs;
     278                 :           0 :       allocate_duration_to_days (&new_model_start_date, new_model_screen_time_per_day,
     279                 :             :                                  start_wall_time_secs, duration_secs);
     280                 :             :     }
     281                 :             : 
     282                 :             :   /* Was the data empty? */
     283   [ #  #  #  # ]:           0 :   if (new_model_screen_time_per_day == NULL || new_model_screen_time_per_day->len == 0)
     284                 :             :     {
     285                 :           0 :       g_set_error (&local_error, G_FILE_ERROR, G_FILE_ERROR_NOENT,
     286                 :           0 :                    _("Failed to load session history data: %s"),
     287                 :             :                    _("Data is empty"));
     288                 :           0 :       g_task_return_error (task, g_steal_pointer (&local_error));
     289                 :           0 :       return;
     290                 :             :     }
     291                 :             : 
     292                 :           0 :   new_model_n_days = new_model_screen_time_per_day->len;
     293                 :             : 
     294                 :           0 :   LoadDataData *data = load_data_data_new (&new_model_start_date,
     295                 :             :                                            new_model_n_days,
     296                 :           0 :                                            (double *) g_array_free (g_steal_pointer (&new_model_screen_time_per_day), FALSE));
     297                 :           0 :   g_task_return_pointer (task, data, (GDestroyNotify) load_data_data_free);
     298                 :             : }
     299                 :             : 
     300                 :             : static void allocate_duration_to_day (const GDate *model_start_date,
     301                 :             :                                       GArray      *model_screen_time_per_day,
     302                 :             :                                       GDateTime   *start_date_time,
     303                 :             :                                       uint64_t     duration_secs);
     304                 :             : 
     305                 :             : /* Take the time period [start_wall_time_secs, start_wall_time_secs + duration_secs]
     306                 :             :  * and add it to the model, splitting it between day boundaries if needed, and
     307                 :             :  * extending the `GArray` if needed. */
     308                 :             : static void
     309                 :           0 : allocate_duration_to_days (const GDate *model_start_date,
     310                 :             :                            GArray      *model_screen_time_per_day,
     311                 :             :                            uint64_t     start_wall_time_secs,
     312                 :             :                            uint64_t     duration_secs)
     313                 :             : {
     314                 :           0 :   g_autoptr(GDateTime) start_date_time = NULL;
     315                 :             : 
     316                 :           0 :   start_date_time = g_date_time_new_from_unix_local (start_wall_time_secs);
     317                 :             : 
     318         [ #  # ]:           0 :   while (duration_secs > 0)
     319                 :             :     {
     320                 :           0 :       g_autoptr(GDateTime) start_of_day = NULL, start_of_next_day = NULL;
     321                 :           0 :       g_autoptr(GDateTime) new_start_date_time = NULL;
     322                 :             :       GTimeSpan span_usecs;
     323                 :             :       uint64_t span_secs;
     324                 :             : 
     325                 :           0 :       start_of_day = g_date_time_new_local (g_date_time_get_year (start_date_time),
     326                 :             :                                             g_date_time_get_month (start_date_time),
     327                 :             :                                             g_date_time_get_day_of_month (start_date_time),
     328                 :             :                                             0, 0, 0);
     329                 :           0 :       g_assert (start_of_day != NULL);
     330                 :           0 :       start_of_next_day = g_date_time_add_days (start_of_day, 1);
     331                 :           0 :       g_assert (start_of_next_day != NULL);
     332                 :             : 
     333                 :           0 :       span_usecs = g_date_time_difference (start_of_next_day, start_date_time);
     334                 :           0 :       span_secs = span_usecs / G_USEC_PER_SEC;
     335         [ #  # ]:           0 :       if (span_secs > duration_secs)
     336                 :           0 :         span_secs = duration_secs;
     337                 :             : 
     338                 :           0 :       allocate_duration_to_day (model_start_date, model_screen_time_per_day,
     339                 :             :                                 start_date_time, span_secs);
     340                 :             : 
     341                 :           0 :       duration_secs -= span_secs;
     342                 :           0 :       new_start_date_time = g_date_time_add_seconds (start_date_time, span_secs);
     343                 :           0 :       g_date_time_unref (start_date_time);
     344                 :           0 :       start_date_time = g_steal_pointer (&new_start_date_time);
     345                 :             :     }
     346                 :           0 : }
     347                 :             : 
     348                 :             : /* Take the time period [start_date_time, start_date_time + duration_secs]
     349                 :             :  * and add it to the model, extending the `GArray` if needed. The time period
     350                 :             :  * *must not* cross a day boundary, i.e. it’s invalid to call this function
     351                 :             :  * with `start_date_time` as 23:00 on a day, and `duration_secs` as 2h.
     352                 :             :  *
     353                 :             :  * Note that @model_screen_time_per_day is in minutes, whereas @duration_secs
     354                 :             :  * is in seconds. */
     355                 :             : static void
     356                 :           0 : allocate_duration_to_day (const GDate *model_start_date,
     357                 :             :                           GArray      *model_screen_time_per_day,
     358                 :             :                           GDateTime   *start_date_time,
     359                 :             :                           uint64_t     duration_secs)
     360                 :             : {
     361                 :             :   GDate start_date;
     362                 :             :   int diff_days;
     363                 :             :   double *element;
     364                 :             : 
     365                 :           0 :   g_date_clear (&start_date, 1);
     366                 :           0 :   g_date_set_dmy (&start_date,
     367                 :           0 :                   g_date_time_get_day_of_month (start_date_time),
     368                 :           0 :                   g_date_time_get_month (start_date_time),
     369                 :           0 :                   g_date_time_get_year (start_date_time));
     370                 :             : 
     371                 :           0 :   diff_days = g_date_days_between (model_start_date, &start_date);
     372                 :           0 :   g_assert (diff_days >= 0);
     373                 :             : 
     374                 :             :   /* If the new day is outside the range of the model, insert it at the right
     375                 :             :    * index. This will automatically create the indices between, and initialise
     376                 :             :    * them to zero, which is what we want. */
     377         [ #  # ]:           0 :   if ((unsigned int) diff_days >= model_screen_time_per_day->len)
     378                 :             :     {
     379                 :           0 :       const double new_val = 0.0;
     380                 :           0 :       g_array_insert_val (model_screen_time_per_day, diff_days, new_val);
     381                 :             :     }
     382                 :             : 
     383                 :           0 :   element = &g_array_index (model_screen_time_per_day, double, diff_days);
     384                 :           0 :   *element += duration_secs / 60.0;
     385                 :           0 : }
     386                 :             : 
     387                 :             : static gboolean
     388                 :           0 : mct_screen_time_statistics_row_load_data_finish (CcScreenTimeStatisticsRow  *screen_time_statistics_row,
     389                 :             :                                                  GAsyncResult               *result,
     390                 :             :                                                  GDate                      *out_new_model_start_date,
     391                 :             :                                                  size_t                     *out_new_model_n_days,
     392                 :             :                                                  double                    **out_new_model_screen_time_per_day,
     393                 :             :                                                  GError                    **error)
     394                 :             : {
     395                 :           0 :   g_autoptr(LoadDataData) data = NULL;
     396                 :             : 
     397                 :           0 :   g_return_val_if_fail (g_task_is_valid (result, screen_time_statistics_row), FALSE);
     398                 :             : 
     399                 :             :   /* Set up in case of error. */
     400         [ #  # ]:           0 :   if (out_new_model_start_date != NULL)
     401                 :           0 :     g_date_clear (out_new_model_start_date, 1);
     402         [ #  # ]:           0 :   if (out_new_model_n_days != NULL)
     403                 :           0 :     *out_new_model_n_days = 0;
     404         [ #  # ]:           0 :   if (out_new_model_screen_time_per_day != NULL)
     405                 :           0 :     *out_new_model_screen_time_per_day = NULL;
     406                 :             : 
     407                 :           0 :   data = g_task_propagate_pointer (G_TASK (result), error);
     408                 :             : 
     409         [ #  # ]:           0 :   if (data == NULL)
     410                 :           0 :     return FALSE;
     411                 :             : 
     412                 :             :   /* Success! */
     413         [ #  # ]:           0 :   if (out_new_model_start_date != NULL)
     414                 :           0 :     *out_new_model_start_date = *data->start_date;
     415         [ #  # ]:           0 :   if (out_new_model_n_days != NULL)
     416                 :           0 :     *out_new_model_n_days = data->n_days;
     417         [ #  # ]:           0 :   if (out_new_model_screen_time_per_day != NULL)
     418                 :           0 :     *out_new_model_screen_time_per_day = g_steal_pointer (&data->screen_time_per_day);
     419                 :             : 
     420                 :           0 :   return TRUE;
     421                 :             : }
     422                 :             : 
     423                 :             : static void
     424                 :           0 : usage_changed_cb (GDBusConnection *connection,
     425                 :             :                   const char      *sender_name,
     426                 :             :                   const char      *object_path,
     427                 :             :                   const char      *interface_name,
     428                 :             :                   const char      *signal_name,
     429                 :             :                   GVariant        *parameters,
     430                 :             :                   void            *user_data)
     431                 :             : {
     432                 :           0 :   MctScreenTimeStatisticsRow *self = MCT_SCREEN_TIME_STATISTICS_ROW (user_data);
     433                 :             : 
     434                 :           0 :   cc_screen_time_statistics_row_update_model (CC_SCREEN_TIME_STATISTICS_ROW (self));
     435                 :           0 : }
     436                 :             : 
     437                 :             : static void
     438                 :           0 : mct_screen_time_statistics_row_class_init (MctScreenTimeStatisticsRowClass *klass)
     439                 :             : {
     440                 :           0 :   GObjectClass *object_class = G_OBJECT_CLASS (klass);
     441                 :           0 :   CcScreenTimeStatisticsRowClass *screen_time_statistics_row_class = CC_SCREEN_TIME_STATISTICS_ROW_CLASS (klass);
     442                 :             : 
     443                 :           0 :   object_class->get_property = mct_screen_time_statistics_row_get_property;
     444                 :           0 :   object_class->set_property = mct_screen_time_statistics_row_set_property;
     445                 :           0 :   object_class->constructed = mct_screen_time_statistics_row_constructed;
     446                 :           0 :   object_class->dispose = mct_screen_time_statistics_row_dispose;
     447                 :             : 
     448                 :           0 :   screen_time_statistics_row_class->load_data_async = mct_screen_time_statistics_row_load_data_async;
     449                 :           0 :   screen_time_statistics_row_class->load_data_finish = mct_screen_time_statistics_row_load_data_finish;
     450                 :             : 
     451                 :             :   /**
     452                 :             :    * MctScreenTimeStatisticsRow:connection: (not nullable)
     453                 :             :    *
     454                 :             :    * A connection to the system bus, where malcontent-timerd runs.
     455                 :             :    *
     456                 :             :    * It’s provided to allow an existing connection to be re-used and for testing
     457                 :             :    * purposes.
     458                 :             :    *
     459                 :             :    * Since 0.14.0
     460                 :             :    */
     461                 :           0 :   properties[PROP_CONNECTION] = g_param_spec_object ("connection", NULL, NULL,
     462                 :             :                                                      G_TYPE_DBUS_CONNECTION,
     463                 :             :                                                      G_PARAM_READWRITE |
     464                 :             :                                                      G_PARAM_CONSTRUCT_ONLY |
     465                 :             :                                                      G_PARAM_STATIC_STRINGS);
     466                 :             : 
     467                 :             :   /**
     468                 :             :    * MctScreenTimeStatisticsRow:uid:
     469                 :             :    *
     470                 :             :    * The selected user’s UID.
     471                 :             :    *
     472                 :             :    * Since 0.14.0
     473                 :             :    */
     474                 :           0 :   properties[PROP_UID] = g_param_spec_uint ("uid", NULL, NULL,
     475                 :             :                                             0, G_MAXUINT, 0,
     476                 :             :                                             G_PARAM_READWRITE |
     477                 :             :                                             G_PARAM_CONSTRUCT_ONLY |
     478                 :             :                                             G_PARAM_STATIC_STRINGS);
     479                 :             : 
     480                 :           0 :   g_object_class_install_properties (object_class, G_N_ELEMENTS (properties), properties);
     481                 :           0 : }
     482                 :             : 
     483                 :             : static void
     484                 :           0 : mct_screen_time_statistics_row_init (MctScreenTimeStatisticsRow *self)
     485                 :             : {
     486                 :           0 : }
     487                 :             : 
     488                 :             : /**
     489                 :             :  * mct_screen_time_statistics_row_new:
     490                 :             :  * @connection: (transfer none): a D-Bus connection to use
     491                 :             :  * @uid: user ID to use
     492                 :             :  *
     493                 :             :  * Create a new [class@Malcontent.ScreenTimeStatisticsRow] widget.
     494                 :             :  *
     495                 :             :  * Returns: (transfer full): a new screen time statistics row
     496                 :             :  * Since: 0.14.0
     497                 :             :  */
     498                 :             : MctScreenTimeStatisticsRow *
     499                 :           0 : mct_screen_time_statistics_row_new (GDBusConnection *connection,
     500                 :             :                                     uid_t            uid)
     501                 :             : {
     502                 :           0 :   g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
     503                 :             : 
     504                 :           0 :   return g_object_new (MCT_TYPE_SCREEN_TIME_STATISTICS_ROW,
     505                 :             :                        "connection", connection,
     506                 :             :                        "uid", uid,
     507                 :             :                        NULL);
     508                 :             : }
        

Generated by: LCOV version 2.0-1