LCOV - code coverage report
Current view: top level - src/plugins/systemvolume - valent-systemvolume-device.c (source / functions) Coverage Total Hit
Test: Code Coverage Lines: 93.7 % 223 209
Test Date: 2024-11-16 20:34:14 Functions: 100.0 % 23 23
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 60.8 % 130 79

             Branch data     Line data    Source code
       1                 :             : // SPDX-License-Identifier: GPL-3.0-or-later
       2                 :             : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
       3                 :             : 
       4                 :             : #define G_LOG_DOMAIN "valent-systemvolume-device"
       5                 :             : 
       6                 :             : #include "config.h"
       7                 :             : 
       8                 :             : #include <inttypes.h>
       9                 :             : #include <math.h>
      10                 :             : 
      11                 :             : #include <gio/gio.h>
      12                 :             : #include <libtracker-sparql/tracker-sparql.h>
      13                 :             : #include <valent.h>
      14                 :             : 
      15                 :             : #include "valent-systemvolume-device.h"
      16                 :             : 
      17                 :             : static inline void
      18                 :           5 : valent_device_send_packet_cb (ValentDevice *device,
      19                 :             :                               GAsyncResult *result,
      20                 :             :                               gpointer      user_data)
      21                 :             : {
      22                 :          10 :   g_autoptr (GError) error = NULL;
      23                 :             : 
      24         [ -  + ]:           5 :   if (!valent_device_send_packet_finish (device, result, &error))
      25                 :             :     {
      26         [ #  # ]:           0 :       if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED))
      27                 :           0 :         g_critical ("%s(): %s", G_STRFUNC, error->message);
      28         [ #  # ]:           0 :       else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_CONNECTED))
      29                 :           0 :         g_warning ("%s(): %s", G_STRFUNC, error->message);
      30         [ #  # ]:           0 :       else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
      31                 :           0 :         g_debug ("%s(): %s", G_STRFUNC, error->message);
      32                 :             :     }
      33                 :           5 : }
      34                 :             : 
      35                 :             : #define VALENT_TYPE_SYSTEMVOLUME_STREAM (valent_systemvolume_stream_get_type ())
      36   [ +  -  +  -  :           4 : G_DECLARE_FINAL_TYPE (ValentSystemvolumeStream, valent_systemvolume_stream, VALENT, SYSTEMVOLUME_STREAM, ValentMixerStream)
                   -  + ]
      37                 :             : 
      38                 :             : struct _ValentSystemvolumeStream
      39                 :             : {
      40                 :             :   ValentMixerStream  parent_instance;
      41                 :             : 
      42                 :             :   ValentDevice      *device;
      43                 :             :   GCancellable      *cancellable;
      44                 :             : 
      45                 :             :   int64_t            max_volume;
      46                 :             :   int64_t            volume;
      47                 :             :   unsigned int       muted : 1;
      48                 :             : };
      49                 :             : 
      50   [ +  +  +  - ]:           8 : G_DEFINE_FINAL_TYPE (ValentSystemvolumeStream, valent_systemvolume_stream, VALENT_TYPE_MIXER_STREAM)
      51                 :             : 
      52                 :             : /*
      53                 :             :  * ValentMixerStream
      54                 :             :  */
      55                 :             : static unsigned int
      56                 :           1 : valent_systemvolume_stream_get_level (ValentMixerStream *stream)
      57                 :             : {
      58                 :           1 :   ValentSystemvolumeStream *self = VALENT_SYSTEMVOLUME_STREAM (stream);
      59                 :           1 :   double percent;
      60                 :             : 
      61         [ +  - ]:           1 :   g_assert (VALENT_IS_SYSTEMVOLUME_STREAM (self));
      62                 :             : 
      63                 :           1 :   percent = (double)self->volume / (double)self->max_volume;
      64                 :             : 
      65                 :           1 :   return (unsigned int)round (percent * 100.0);
      66                 :             : }
      67                 :             : 
      68                 :             : static void
      69                 :           1 : valent_systemvolume_stream_set_level (ValentMixerStream *stream,
      70                 :             :                                       unsigned int       level)
      71                 :             : {
      72                 :           1 :   ValentSystemvolumeStream *self = VALENT_SYSTEMVOLUME_STREAM (stream);
      73                 :           2 :   g_autoptr (JsonBuilder) builder = NULL;
      74         [ -  + ]:           1 :   g_autoptr (JsonNode) packet = NULL;
      75                 :           1 :   double percent;
      76                 :           1 :   int64_t volume;
      77                 :             : 
      78         [ +  - ]:           1 :   g_assert (VALENT_IS_SYSTEMVOLUME_STREAM (self));
      79                 :             : 
      80                 :           1 :   percent = (double)level / 100.0;
      81                 :           1 :   volume = (int64_t)round (percent * self->max_volume);
      82                 :             : 
      83                 :           1 :   valent_packet_init (&builder,  "kdeconnect.systemvolume.request");
      84                 :           1 :   json_builder_set_member_name (builder, "name");
      85                 :           1 :   json_builder_add_string_value (builder, valent_mixer_stream_get_name (stream));
      86                 :           1 :   json_builder_set_member_name (builder, "volume");
      87                 :           1 :   json_builder_add_int_value (builder, volume);
      88                 :           1 :   packet = valent_packet_end (&builder);
      89                 :             : 
      90         [ +  - ]:           1 :   valent_device_send_packet (self->device,
      91                 :             :                              packet,
      92                 :             :                              NULL, /* cancellable */
      93                 :             :                              (GAsyncReadyCallback) valent_device_send_packet_cb,
      94                 :             :                              NULL);
      95                 :           1 : }
      96                 :             : 
      97                 :             : static gboolean
      98                 :           1 : valent_systemvolume_stream_get_muted (ValentMixerStream *stream)
      99                 :             : {
     100                 :           1 :   ValentSystemvolumeStream *self = VALENT_SYSTEMVOLUME_STREAM (stream);
     101                 :             : 
     102         [ +  - ]:           1 :   g_assert (VALENT_IS_SYSTEMVOLUME_STREAM (self));
     103                 :             : 
     104                 :           1 :   return self->muted;
     105                 :             : }
     106                 :             : 
     107                 :             : static void
     108                 :           1 : valent_systemvolume_stream_set_muted (ValentMixerStream *stream,
     109                 :             :                                       gboolean           state)
     110                 :             : {
     111                 :           1 :   ValentSystemvolumeStream *self = VALENT_SYSTEMVOLUME_STREAM (stream);
     112                 :           2 :   g_autoptr (JsonBuilder) builder = NULL;
     113         [ -  + ]:           1 :   g_autoptr (JsonNode) packet = NULL;
     114                 :             : 
     115         [ +  - ]:           1 :   g_assert (VALENT_IS_SYSTEMVOLUME_STREAM (self));
     116                 :             : 
     117                 :           1 :   valent_packet_init (&builder, "kdeconnect.systemvolume.request");
     118                 :           1 :   json_builder_set_member_name (builder, "name");
     119                 :           1 :   json_builder_add_string_value (builder, valent_mixer_stream_get_name (stream));
     120                 :           1 :   json_builder_set_member_name (builder, "muted");
     121                 :           1 :   json_builder_add_boolean_value (builder, state);
     122                 :           1 :   packet = valent_packet_end (&builder);
     123                 :             : 
     124         [ +  - ]:           1 :   valent_device_send_packet (self->device,
     125                 :             :                              packet,
     126                 :             :                              NULL, /* cancellable */
     127                 :             :                              (GAsyncReadyCallback) valent_device_send_packet_cb,
     128                 :             :                              NULL);
     129                 :           1 : }
     130                 :             : 
     131                 :             : static void
     132                 :           7 : valent_systemvolume_stream_update (ValentMixerStream *stream,
     133                 :             :                                    JsonObject        *state)
     134                 :             : {
     135                 :           7 :   ValentSystemvolumeStream *self = VALENT_SYSTEMVOLUME_STREAM (stream);
     136                 :           7 :   JsonNode *node;
     137                 :             : 
     138                 :           7 :   node = json_object_get_member (state, "maxVolume");
     139         [ +  + ]:           7 :   if (node != NULL)
     140                 :             :     {
     141         [ +  - ]:           4 :       if (json_node_get_value_type (node) == G_TYPE_INT64)
     142                 :             :         {
     143                 :           4 :           self->max_volume = json_node_get_int (node);
     144                 :             :         }
     145                 :             :       else
     146                 :             :         {
     147                 :           0 :           g_warning ("%s(): expected \"maxVolume\" field holding an integer",
     148                 :             :                      G_STRFUNC);
     149                 :             :         }
     150                 :             :     }
     151                 :             : 
     152                 :           7 :   node = json_object_get_member (state, "muted");
     153         [ +  + ]:           7 :   if (node != NULL)
     154                 :             :     {
     155         [ +  - ]:           5 :       if (json_node_get_value_type (node) == G_TYPE_BOOLEAN)
     156                 :             :         {
     157                 :           5 :           gboolean muted = json_node_get_boolean (node);
     158         [ +  + ]:           5 :           if (self->muted != muted)
     159                 :             :             {
     160                 :           2 :               self->muted = muted;
     161                 :           2 :               g_object_notify (G_OBJECT (self), "muted");
     162                 :             :             }
     163                 :             :         }
     164                 :             :       else
     165                 :             :         {
     166                 :           0 :           g_warning ("%s(): expected \"muted\" field holding a boolean",
     167                 :             :                      G_STRFUNC);
     168                 :             :         }
     169                 :             :     }
     170                 :             : 
     171                 :           7 :   node = json_object_get_member (state, "volume");
     172         [ +  + ]:           7 :   if (node != NULL)
     173                 :             :     {
     174         [ +  - ]:           5 :       if (json_node_get_value_type (node) == G_TYPE_INT64)
     175                 :             :         {
     176                 :           5 :           int64_t volume = json_node_get_int (node);
     177         [ +  + ]:           5 :           if (self->volume != volume)
     178                 :             :             {
     179                 :           4 :               self->volume = volume;
     180                 :           4 :               g_object_notify (G_OBJECT (self), "level");
     181                 :             :             }
     182                 :             :         }
     183                 :             :       else
     184                 :             :         {
     185                 :           0 :           g_warning ("%s(): expected \"volume\" field holding an integer",
     186                 :             :                      G_STRFUNC);
     187                 :             :         }
     188                 :             :     }
     189                 :           7 : }
     190                 :             : 
     191                 :             : static void
     192                 :           1 : valent_systemvolume_stream_class_init (ValentSystemvolumeStreamClass *klass)
     193                 :             : {
     194                 :           1 :   ValentMixerStreamClass *stream_class = VALENT_MIXER_STREAM_CLASS (klass);
     195                 :             : 
     196                 :           1 :   stream_class->get_level = valent_systemvolume_stream_get_level;
     197                 :           1 :   stream_class->set_level = valent_systemvolume_stream_set_level;
     198                 :           1 :   stream_class->get_muted = valent_systemvolume_stream_get_muted;
     199                 :           1 :   stream_class->set_muted = valent_systemvolume_stream_set_muted;
     200                 :             : }
     201                 :             : 
     202                 :             : static void
     203                 :           2 : valent_systemvolume_stream_init (ValentSystemvolumeStream *self)
     204                 :             : {
     205                 :           2 : }
     206                 :             : 
     207                 :             : 
     208                 :             : /* <private>
     209                 :             :  * ValentSystemvolumeDevice:
     210                 :             :  *
     211                 :             :  * A `ValentMixerAdapter` for KDE Connect devices.
     212                 :             :  */
     213                 :             : struct _ValentSystemvolumeDevice
     214                 :             : {
     215                 :             :   ValentMixerAdapter  parent_instance;
     216                 :             : 
     217                 :             :   ValentDevice       *device;
     218                 :             :   GCancellable       *cancellable;
     219                 :             :   ValentMixerStream  *default_output;
     220                 :             :   GHashTable         *outputs;
     221                 :             : };
     222                 :             : 
     223   [ +  +  +  - ]:          21 : G_DEFINE_FINAL_TYPE (ValentSystemvolumeDevice, valent_systemvolume_device, VALENT_TYPE_MIXER_ADAPTER)
     224                 :             : 
     225                 :             : /*
     226                 :             :  * ValentMixerAdapter
     227                 :             :  */
     228                 :             : static void
     229                 :           8 : on_device_state_changed (ValentDevice             *device,
     230                 :             :                          GParamSpec               *pspec,
     231                 :             :                          ValentSystemvolumeDevice *self)
     232                 :             : {
     233                 :           8 :   ValentDeviceState state = VALENT_DEVICE_STATE_NONE;
     234                 :           8 :   gboolean available;
     235                 :             : 
     236         [ +  - ]:           8 :   g_assert (VALENT_IS_SYSTEMVOLUME_DEVICE (self));
     237                 :             : 
     238                 :           8 :   state = valent_device_get_state (device);
     239                 :           8 :   available = (state & VALENT_DEVICE_STATE_CONNECTED) != 0 &&
     240                 :             :               (state & VALENT_DEVICE_STATE_PAIRED) != 0;
     241                 :             : 
     242         [ +  + ]:           8 :   if (available)
     243                 :             :     {
     244                 :           2 :       g_autoptr (JsonBuilder) builder = NULL;
     245         [ -  + ]:           2 :       g_autoptr (JsonNode) packet = NULL;
     246         [ +  - ]:           2 :       g_autoptr (GCancellable) cancellable = NULL;
     247                 :             : 
     248                 :           2 :       cancellable = g_cancellable_new ();
     249                 :           2 :       self->cancellable = valent_object_chain_cancellable (VALENT_OBJECT (self),
     250                 :             :                                                            cancellable);
     251                 :             : 
     252                 :           2 :       valent_packet_init (&builder, "kdeconnect.systemvolume.request");
     253                 :           2 :       json_builder_set_member_name (builder, "requestSinks");
     254                 :           2 :       json_builder_add_boolean_value (builder, TRUE);
     255                 :           2 :       packet = valent_packet_end (&builder);
     256                 :             : 
     257         [ +  - ]:           2 :       valent_device_send_packet (self->device,
     258                 :             :                                  packet,
     259                 :             :                                  self->cancellable,
     260                 :             :                                  (GAsyncReadyCallback) valent_device_send_packet_cb,
     261                 :             :                                  NULL);
     262                 :             :     }
     263                 :             :   else
     264                 :             :     {
     265                 :           6 :       GHashTableIter iter;
     266                 :           6 :       ValentMixerStream *output;
     267                 :             : 
     268                 :           6 :       g_cancellable_cancel (self->cancellable);
     269         [ +  + ]:           6 :       g_clear_object (&self->cancellable);
     270                 :             : 
     271                 :           6 :       g_hash_table_iter_init (&iter, self->outputs);
     272         [ +  + ]:           7 :       while (g_hash_table_iter_next (&iter, NULL, (void **)&output))
     273                 :             :         {
     274                 :           1 :           valent_mixer_adapter_stream_removed (VALENT_MIXER_ADAPTER (self),
     275                 :             :                                                output);
     276                 :           1 :           g_hash_table_iter_remove (&iter);
     277                 :             :         }
     278                 :             :     }
     279                 :           8 : }
     280                 :             : 
     281                 :             : static ValentMixerStream  *
     282                 :           2 : valent_systemvolume_device_get_default_output (ValentMixerAdapter *adapter)
     283                 :             : {
     284                 :           2 :   ValentSystemvolumeDevice *self = VALENT_SYSTEMVOLUME_DEVICE (adapter);
     285                 :             : 
     286         [ +  - ]:           2 :   g_assert (VALENT_IS_SYSTEMVOLUME_DEVICE (self));
     287                 :             : 
     288                 :           2 :   return self->default_output;
     289                 :             : }
     290                 :             : 
     291                 :             : static void
     292                 :           1 : valent_systemvolume_device_set_default_output (ValentMixerAdapter *adapter,
     293                 :             :                                                ValentMixerStream  *stream)
     294                 :             : {
     295                 :           1 :   ValentSystemvolumeDevice *self = VALENT_SYSTEMVOLUME_DEVICE (adapter);
     296                 :           1 :   g_autoptr (JsonBuilder) builder = NULL;
     297   [ -  -  -  + ]:           1 :   g_autoptr (JsonNode) packet = NULL;
     298                 :             : 
     299                 :             : 
     300         [ +  - ]:           1 :   g_assert (VALENT_IS_SYSTEMVOLUME_DEVICE (self));
     301                 :             : 
     302         [ -  + ]:           1 :   if (self->default_output == stream)
     303         [ #  # ]:           0 :     return;
     304                 :             : 
     305                 :           1 :   valent_packet_init (&builder, "kdeconnect.systemvolume.request");
     306                 :           1 :   json_builder_set_member_name (builder, "name");
     307                 :           1 :   json_builder_add_string_value (builder, valent_mixer_stream_get_name (stream));
     308                 :           1 :   json_builder_set_member_name (builder, "enabled");
     309                 :           1 :   json_builder_add_boolean_value (builder, TRUE);
     310                 :           1 :   packet = valent_packet_end (&builder);
     311                 :             : 
     312         [ +  - ]:           1 :   valent_device_send_packet (self->device,
     313                 :             :                              packet,
     314                 :             :                              self->cancellable,
     315                 :             :                              (GAsyncReadyCallback) valent_device_send_packet_cb,
     316                 :             :                              NULL);
     317                 :             : }
     318                 :             : 
     319                 :             : /*
     320                 :             :  * GObject
     321                 :             :  */
     322                 :             : static void
     323                 :           2 : valent_systemvolume_device_constructed (GObject *object)
     324                 :             : {
     325                 :           2 :   ValentSystemvolumeDevice *self = VALENT_SYSTEMVOLUME_DEVICE (object);
     326                 :             : 
     327                 :           2 :   G_OBJECT_CLASS (valent_systemvolume_device_parent_class)->constructed (object);
     328                 :             : 
     329                 :           2 :   self->device = valent_extension_get_object (VALENT_EXTENSION (self));
     330                 :           2 :   g_signal_connect_object (self->device,
     331                 :             :                            "notify::state",
     332                 :             :                            G_CALLBACK (on_device_state_changed),
     333                 :             :                            self,
     334                 :             :                            G_CONNECT_DEFAULT);
     335                 :           2 :   on_device_state_changed (self->device, NULL, self);
     336                 :           2 : }
     337                 :             : 
     338                 :             : static void
     339                 :           2 : valent_systemvolume_device_finalize (GObject *object)
     340                 :             : {
     341                 :           2 :   ValentSystemvolumeDevice *self = VALENT_SYSTEMVOLUME_DEVICE (object);
     342                 :             : 
     343         [ -  + ]:           2 :   g_clear_object (&self->cancellable);
     344         [ +  + ]:           2 :   g_clear_object (&self->default_output);
     345         [ +  - ]:           2 :   g_clear_pointer (&self->outputs, g_hash_table_unref);
     346                 :             : 
     347                 :           2 :   G_OBJECT_CLASS (valent_systemvolume_device_parent_class)->finalize (object);
     348                 :           2 : }
     349                 :             : 
     350                 :             : static void
     351                 :           1 : valent_systemvolume_device_class_init (ValentSystemvolumeDeviceClass *klass)
     352                 :             : {
     353                 :           1 :   GObjectClass *object_class = G_OBJECT_CLASS (klass);
     354                 :           1 :   ValentMixerAdapterClass *adapter_class = VALENT_MIXER_ADAPTER_CLASS (klass);
     355                 :             : 
     356                 :           1 :   object_class->constructed = valent_systemvolume_device_constructed;
     357                 :           1 :   object_class->finalize = valent_systemvolume_device_finalize;
     358                 :             : 
     359                 :           1 :   adapter_class->get_default_output = valent_systemvolume_device_get_default_output;
     360                 :           1 :   adapter_class->set_default_output = valent_systemvolume_device_set_default_output;
     361                 :             : }
     362                 :             : 
     363                 :             : static void
     364                 :           2 : valent_systemvolume_device_init (ValentSystemvolumeDevice *self)
     365                 :             : {
     366                 :           2 :   self->outputs = g_hash_table_new_full (g_str_hash, g_str_equal,
     367                 :             :                                          g_free, g_object_unref);
     368                 :           2 : }
     369                 :             : 
     370                 :             : /**
     371                 :             :  * valent_systemvolume_device_new:
     372                 :             :  * @device: a `ValentDevice`
     373                 :             :  *
     374                 :             :  * Create a new `ValentSystemvolumeDevice`.
     375                 :             :  *
     376                 :             :  * Returns: (transfer full): a new message store
     377                 :             :  */
     378                 :             : ValentMixerAdapter *
     379                 :           2 : valent_systemvolume_device_new (ValentDevice *device)
     380                 :             : {
     381                 :           4 :   g_autoptr (ValentContext) context = NULL;
     382         [ +  - ]:           2 :   g_autofree char *iri = NULL;
     383                 :             : 
     384         [ +  - ]:           2 :   g_return_val_if_fail (VALENT_IS_DEVICE (device), NULL);
     385                 :             : 
     386                 :           2 :   context = valent_context_new (valent_device_get_context (device),
     387                 :             :                                 "plugin",
     388                 :             :                                 "systemvolume");
     389                 :           2 :   iri = tracker_sparql_escape_uri_printf ("urn:valent:mixer:%s",
     390                 :             :                                           valent_device_get_id (device));
     391                 :           2 :   return g_object_new (VALENT_TYPE_SYSTEMVOLUME_DEVICE,
     392                 :             :                        "iri",     iri,
     393                 :             :                        "object",  device,
     394                 :             :                        "context", context,
     395                 :             :                        NULL);
     396                 :             : }
     397                 :             : 
     398                 :             : static const char *
     399                 :           7 : valent_systemvolume_device_handle_stream (ValentSystemvolumeDevice *self,
     400                 :             :                                           JsonObject               *state)
     401                 :             : {
     402                 :           7 :   ValentMixerStream *stream = NULL;
     403                 :           7 :   gboolean new_stream = FALSE;
     404                 :           7 :   JsonNode *node;
     405                 :           7 :   const char *name = NULL;
     406                 :             : 
     407                 :           7 :   node = json_object_get_member (state, "name");
     408   [ +  -  -  + ]:           7 :   if (node == NULL || json_node_get_value_type (node) != G_TYPE_STRING)
     409                 :             :     {
     410                 :           0 :       g_warning ("%s(): expected \"name\" field holding a string", G_STRFUNC);
     411                 :           0 :       return NULL;
     412                 :             :     }
     413                 :           7 :   name = json_node_get_string (node);
     414                 :             : 
     415                 :           7 :   stream = g_hash_table_lookup (self->outputs, name);
     416         [ +  + ]:           7 :   if (stream == NULL)
     417                 :             :     {
     418                 :           2 :       const char *description = NULL;
     419                 :             : 
     420                 :           2 :       node = json_object_get_member (state, "description");
     421         [ -  + ]:           2 :       if (node != NULL)
     422                 :             :         {
     423         [ +  - ]:           2 :           if (json_node_get_value_type (node) == G_TYPE_STRING)
     424                 :             :             {
     425                 :           2 :               description = json_node_get_string (node);
     426                 :             :             }
     427                 :             :           else
     428                 :             :             {
     429                 :           0 :               g_warning ("%s(): expected \"description\" field holding a string",
     430                 :             :                          G_STRFUNC);
     431                 :             :             }
     432                 :             :         }
     433                 :             : 
     434                 :           2 :       stream = g_object_new (VALENT_TYPE_SYSTEMVOLUME_STREAM,
     435                 :             :                              "name",        name,
     436                 :             :                              "description", description,
     437                 :             :                              "direction",   VALENT_MIXER_OUTPUT,
     438                 :             :                              NULL);
     439                 :           2 :       ((ValentSystemvolumeStream *)stream)->device = self->device;
     440                 :           2 :       ((ValentSystemvolumeStream *)stream)->cancellable = self->cancellable;
     441         [ -  + ]:           2 :       g_hash_table_replace (self->outputs, g_strdup (name), stream /* owned */);
     442                 :           2 :       new_stream = TRUE;
     443                 :             :     }
     444                 :             : 
     445                 :           7 :   valent_systemvolume_stream_update (stream, state);
     446                 :             : 
     447                 :           7 :   node = json_object_get_member (state, "enabled");
     448         [ +  - ]:           7 :   if (node != NULL)
     449                 :             :     {
     450         [ +  - ]:           7 :       if (json_node_get_value_type (node) == G_TYPE_BOOLEAN)
     451                 :             :         {
     452   [ +  +  +  + ]:          13 :           if (json_node_get_boolean (node) &&
     453                 :           6 :               g_set_object (&self->default_output, stream))
     454                 :             :             {
     455                 :           3 :               g_object_notify (G_OBJECT (self), "default-output");
     456                 :             :             }
     457                 :             :         }
     458                 :             :       else
     459                 :             :         {
     460                 :           0 :           g_warning ("%s(): expected \"enabled\" field holding a boolean",
     461                 :             :                      G_STRFUNC);
     462                 :             :         }
     463                 :             :     }
     464                 :             : 
     465         [ +  + ]:           7 :   if (new_stream)
     466                 :           2 :     valent_mixer_adapter_stream_added (VALENT_MIXER_ADAPTER (self), stream);
     467                 :             : 
     468                 :             :   return name;
     469                 :             : }
     470                 :             : 
     471                 :             : /**
     472                 :             :  * valent_systemvolume_device_handle_packet:
     473                 :             :  * @self: a `ValentSystemvolumeDevice`
     474                 :             :  * @packet: a `kdeconnect.systemvolume.*` packet
     475                 :             :  *
     476                 :             :  * Handle a packet of mixer.
     477                 :             :  */
     478                 :             : void
     479                 :           6 : valent_systemvolume_device_handle_packet (ValentSystemvolumeDevice *self,
     480                 :             :                                           JsonNode                 *packet)
     481                 :             : {
     482                 :           6 :   JsonArray *sinks;
     483                 :             : 
     484                 :           6 :   VALENT_ENTRY;
     485                 :             : 
     486         [ +  - ]:           6 :   g_assert (VALENT_IS_SYSTEMVOLUME_DEVICE (self));
     487         [ -  + ]:           6 :   g_assert (VALENT_IS_PACKET (packet));
     488                 :             : 
     489         [ +  + ]:           6 :   if (valent_packet_get_array (packet, "sinkList", &sinks))
     490                 :             :     {
     491                 :           3 :       g_autoptr (GStrvBuilder) names = NULL;
     492         [ +  - ]:           3 :       g_auto (GStrv) namev = NULL;
     493                 :           3 :       unsigned int n_sinks = 0;
     494                 :           3 :       GHashTableIter iter;
     495                 :           3 :       const char *name = NULL;
     496                 :           3 :       ValentMixerStream *output = NULL;
     497                 :             : 
     498                 :           3 :       names = g_strv_builder_new ();
     499                 :           3 :       n_sinks = json_array_get_length (sinks);
     500         [ +  + ]:           7 :       for (unsigned int i = 0; i < n_sinks; i++)
     501                 :             :         {
     502                 :           4 :           JsonObject *sink = json_array_get_object_element (sinks, i);
     503                 :             : 
     504                 :           4 :           name = valent_systemvolume_device_handle_stream (self, sink);
     505         [ +  - ]:           4 :           if (name != NULL)
     506                 :           4 :             g_strv_builder_add (names, name);
     507                 :             :         }
     508                 :           3 :       namev = g_strv_builder_end (names);
     509                 :             : 
     510                 :           3 :       g_hash_table_iter_init (&iter, self->outputs);
     511         [ +  + ]:          11 :       while (g_hash_table_iter_next (&iter, (void **)&name, (void **)&output))
     512                 :             :         {
     513         [ +  + ]:           5 :           if (!g_strv_contains ((const char * const *)namev, name))
     514                 :             :             {
     515                 :           1 :               valent_mixer_adapter_stream_removed (VALENT_MIXER_ADAPTER (self),
     516                 :             :                                                    output);
     517                 :           1 :               g_hash_table_iter_remove (&iter);
     518                 :             :             }
     519                 :             :         }
     520                 :             :     }
     521                 :             :   else
     522                 :             :     {
     523                 :           3 :       JsonObject *body;
     524                 :             : 
     525                 :           3 :       body = valent_packet_get_body (packet);
     526                 :           3 :       valent_systemvolume_device_handle_stream (self, body);
     527                 :             :     }
     528                 :             : 
     529                 :           6 :   VALENT_EXIT;
     530                 :             : }
     531                 :             : 
        

Generated by: LCOV version 2.0-1