LCOV - code coverage report
Current view: top level - src/plugins/systemvolume - valent-systemvolume-plugin.c (source / functions) Coverage Total Hit
Test: Code Coverage Lines: 90.4 % 218 197
Test Date: 2025-01-26 01:08:22 Functions: 94.4 % 18 17
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 60.0 % 140 84

             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-plugin"
       5                 :             : 
       6                 :             : #include "config.h"
       7                 :             : 
       8                 :             : #include <gio/gio.h>
       9                 :             : #include <json-glib/json-glib.h>
      10                 :             : #include <valent.h>
      11                 :             : 
      12                 :             : #include "valent-systemvolume-device.h"
      13                 :             : 
      14                 :             : #include "valent-systemvolume-plugin.h"
      15                 :             : 
      16                 :             : 
      17                 :             : struct _ValentSystemvolumePlugin
      18                 :             : {
      19                 :             :   ValentDevicePlugin  parent_instance;
      20                 :             : 
      21                 :             :   ValentMixerAdapter *mixer;
      22                 :             :   unsigned int        mixer_watch : 1;
      23                 :             :   GPtrArray          *states;
      24                 :             : 
      25                 :             :   ValentMixerAdapter *adapter;
      26                 :             : };
      27                 :             : 
      28                 :             : static void valent_systemvolume_plugin_handle_request     (ValentSystemvolumePlugin *self,
      29                 :             :                                                            JsonNode                 *packet);
      30                 :             : static void valent_systemvolume_plugin_handle_sink_change (ValentSystemvolumePlugin *self,
      31                 :             :                                                            JsonNode                 *packet);
      32                 :             : static void valent_systemvolume_plugin_send_sinklist      (ValentSystemvolumePlugin *self);
      33                 :             : 
      34   [ +  +  +  - ]:          70 : G_DEFINE_FINAL_TYPE (ValentSystemvolumePlugin, valent_systemvolume_plugin, VALENT_TYPE_DEVICE_PLUGIN)
      35                 :             : 
      36                 :             : 
      37                 :             : /*
      38                 :             :  * Local Mixer
      39                 :             :  */
      40                 :             : typedef struct
      41                 :             : {
      42                 :             :   ValentMixerStream *stream;
      43                 :             :   unsigned long      notify_id;
      44                 :             :   char              *name;
      45                 :             :   char              *description;
      46                 :             :   unsigned int       volume;
      47                 :             :   unsigned int       muted : 1;
      48                 :             :   unsigned int       enabled : 1;
      49                 :             : } StreamState;
      50                 :             : 
      51                 :             : static StreamState *
      52                 :           9 : stream_state_find (ValentSystemvolumePlugin *self,
      53                 :             :                    const char               *name)
      54                 :             : {
      55         [ +  + ]:          11 :   for (unsigned int i = 0; i < self->states->len; i++)
      56                 :             :     {
      57                 :          10 :       StreamState *state = g_ptr_array_index (self->states, i);
      58                 :             : 
      59         [ +  + ]:          10 :       if (g_strcmp0 (state->name, name) == 0)
      60                 :             :         return state;
      61                 :             :     }
      62                 :             : 
      63                 :             :   return NULL;
      64                 :             : }
      65                 :             : 
      66                 :             : static void
      67                 :           4 : on_stream_changed (ValentMixerStream        *stream,
      68                 :             :                    GParamSpec               *pspec,
      69                 :             :                    ValentSystemvolumePlugin *self)
      70                 :             : {
      71                 :           4 :   StreamState *state;
      72                 :           4 :   const char *name;
      73                 :           4 :   const char *description;
      74                 :           4 :   gboolean enabled;
      75                 :           4 :   gboolean muted;
      76                 :           4 :   unsigned int volume;
      77                 :           4 :   g_autoptr (JsonBuilder) builder = NULL;
      78   [ -  +  -  - ]:           4 :   g_autoptr (JsonNode) packet = NULL;
      79                 :             : 
      80         [ +  - ]:           4 :   g_assert (VALENT_IS_MIXER_STREAM (stream));
      81         [ -  + ]:           4 :   g_assert (VALENT_IS_SYSTEMVOLUME_PLUGIN (self));
      82                 :             : 
      83                 :             :   /* If this is an unknown stream, send a new sink list */
      84                 :           4 :   name = valent_mixer_stream_get_name (stream);
      85                 :             : 
      86         [ -  + ]:           4 :   if ((state = stream_state_find (self, name)) == NULL)
      87                 :             :     {
      88                 :           0 :       valent_systemvolume_plugin_send_sinklist (self);
      89                 :           0 :       return;
      90                 :             :     }
      91                 :             : 
      92                 :             :   /* If the description changed it's probably because the port changed, so
      93                 :             :    * update the state and send the whole list */
      94                 :           4 :   description = valent_mixer_stream_get_description (stream);
      95                 :             : 
      96         [ -  + ]:           4 :   if (g_set_str (&state->description, description))
      97                 :             :     {
      98                 :           0 :       valent_systemvolume_plugin_send_sinklist (self);
      99                 :           0 :       return;
     100                 :             :     }
     101                 :             : 
     102                 :             :   /* If none of the other properties changed, there's nothing to update */
     103                 :           4 :   enabled = valent_mixer_adapter_get_default_output (self->mixer) == stream;
     104                 :           4 :   muted = valent_mixer_stream_get_muted (stream);
     105                 :           4 :   volume = valent_mixer_stream_get_level (stream);
     106                 :             : 
     107         [ +  - ]:           4 :   if (state->enabled == enabled &&
     108         [ +  + ]:           4 :       state->muted == muted &&
     109         [ +  - ]:           2 :       state->volume == volume)
     110                 :             :     return;
     111                 :             : 
     112                 :             :   /* Sink update */
     113                 :           4 :   valent_packet_init (&builder, "kdeconnect.systemvolume");
     114                 :           4 :   json_builder_set_member_name (builder, "name");
     115                 :           4 :   json_builder_add_string_value (builder, state->name);
     116                 :             : 
     117         [ +  + ]:           4 :   if (state->muted != muted)
     118                 :             :     {
     119                 :           2 :       state->muted = muted;
     120                 :           2 :       json_builder_set_member_name (builder, "muted");
     121                 :           2 :       json_builder_add_boolean_value (builder, state->muted);
     122                 :             :     }
     123                 :             : 
     124         [ +  + ]:           4 :   if (state->volume != volume)
     125                 :             :     {
     126                 :           2 :       state->volume = volume;
     127                 :           2 :       json_builder_set_member_name (builder, "volume");
     128                 :           2 :       json_builder_add_int_value (builder, state->volume);
     129                 :             :     }
     130                 :             : 
     131         [ -  + ]:           4 :   if (state->enabled != enabled)
     132                 :             :     {
     133                 :           0 :       state->enabled = enabled;
     134                 :           0 :       json_builder_set_member_name (builder, "enabled");
     135                 :           0 :       json_builder_add_boolean_value (builder, state->enabled);
     136                 :             :     }
     137                 :             : 
     138                 :           4 :   packet = valent_packet_end (&builder);
     139                 :             : 
     140         [ +  - ]:           4 :   valent_device_plugin_queue_packet (VALENT_DEVICE_PLUGIN (self), packet);
     141                 :             : }
     142                 :             : 
     143                 :             : static StreamState *
     144                 :           8 : stream_state_new (ValentSystemvolumePlugin *self,
     145                 :             :                   ValentMixerStream        *stream)
     146                 :             : {
     147                 :           8 :   StreamState *state;
     148                 :             : 
     149         [ +  - ]:           8 :   g_assert (VALENT_IS_SYSTEMVOLUME_PLUGIN (self));
     150         [ -  + ]:           8 :   g_assert (VALENT_IS_MIXER_STREAM (stream));
     151                 :             : 
     152                 :           8 :   state = g_new0 (StreamState, 1);
     153                 :           8 :   state->stream = g_object_ref (stream);
     154                 :           8 :   g_signal_connect_object (state->stream,
     155                 :             :                            "notify",
     156                 :             :                            G_CALLBACK (on_stream_changed),
     157                 :             :                            self, 0);
     158                 :             : 
     159         [ -  + ]:           8 :   state->name = g_strdup (valent_mixer_stream_get_name (stream));
     160         [ -  + ]:           8 :   state->description = g_strdup (valent_mixer_stream_get_description (stream));
     161                 :           8 :   state->volume = valent_mixer_stream_get_level (stream);
     162                 :           8 :   state->muted = valent_mixer_stream_get_muted (stream);
     163                 :           8 :   state->enabled = valent_mixer_adapter_get_default_output (self->mixer) == stream;
     164                 :             : 
     165                 :           8 :   return state;
     166                 :             : }
     167                 :             : 
     168                 :             : static void
     169                 :           8 : stream_state_free (gpointer data)
     170                 :             : {
     171                 :           8 :   StreamState *state = data;
     172                 :             : 
     173         [ -  + ]:           8 :   g_clear_signal_handler (&state->notify_id, state->stream);
     174         [ +  - ]:           8 :   g_clear_object (&state->stream);
     175         [ +  - ]:           8 :   g_clear_pointer (&state->name, g_free);
     176         [ +  - ]:           8 :   g_clear_pointer (&state->description, g_free);
     177                 :           8 :   g_clear_pointer (&state, g_free);
     178                 :           8 : }
     179                 :             : 
     180                 :             : static void
     181                 :           0 : on_default_output_changed (ValentMixerAdapter       *adapter,
     182                 :             :                            GParamSpec               *pspec,
     183                 :             :                            ValentSystemvolumePlugin *self)
     184                 :             : {
     185                 :           0 :   ValentMixerStream *default_output = NULL;
     186                 :             : 
     187         [ #  # ]:           0 :   g_assert (VALENT_IS_MIXER_ADAPTER (adapter));
     188         [ #  # ]:           0 :   g_assert (VALENT_IS_SYSTEMVOLUME_PLUGIN (self));
     189                 :             : 
     190                 :           0 :   default_output = valent_mixer_adapter_get_default_output (adapter);
     191                 :             : 
     192         [ #  # ]:           0 :   for (unsigned int i = 0; i < self->states->len; i++)
     193                 :             :     {
     194                 :           0 :       StreamState *state = g_ptr_array_index (self->states, i);
     195                 :             : 
     196                 :           0 :       state->enabled = state->stream == default_output;
     197                 :             :     }
     198                 :             : 
     199                 :             :   /* It's unclear whether the `enabled` field with a value of `false` is
     200                 :             :    * relevant in the protocol, we resend the whole list */
     201                 :           0 :   valent_systemvolume_plugin_send_sinklist (self);
     202                 :           0 : }
     203                 :             : 
     204                 :             : static void
     205                 :           6 : on_items_changed (GListModel               *list,
     206                 :             :                   unsigned int              position,
     207                 :             :                   unsigned int              removed,
     208                 :             :                   unsigned int              added,
     209                 :             :                   ValentSystemvolumePlugin *self)
     210                 :             : {
     211                 :           6 :   unsigned int n_streams = 0;
     212                 :             : 
     213         [ +  - ]:           6 :   g_assert (G_IS_LIST_MODEL (list));
     214         [ -  + ]:           6 :   g_assert (VALENT_IS_SYSTEMVOLUME_PLUGIN (self));
     215                 :             : 
     216                 :           6 :   g_ptr_array_remove_range (self->states, 0, self->states->len);
     217                 :           6 :   n_streams = g_list_model_get_n_items (list);
     218                 :             : 
     219         [ +  + ]:          14 :   for (unsigned int i = 0; i < n_streams; i++)
     220                 :             :     {
     221                 :           8 :       g_autoptr (ValentMixerStream) stream = NULL;
     222                 :             : 
     223                 :           8 :       stream = g_list_model_get_item (list, i);
     224                 :             : 
     225         [ -  + ]:           8 :       if (valent_mixer_stream_get_direction (stream) != VALENT_MIXER_OUTPUT)
     226         [ #  # ]:           0 :         continue;
     227                 :             : 
     228         [ +  - ]:           8 :       g_ptr_array_add (self->states, stream_state_new (self, stream));
     229                 :             :     }
     230                 :             : 
     231                 :           6 :   valent_systemvolume_plugin_send_sinklist (self);
     232                 :           6 : }
     233                 :             : 
     234                 :             : static void
     235                 :           4 : on_primary_adapter_changed (ValentMixer              *mixer,
     236                 :             :                             GParamSpec               *pspec,
     237                 :             :                             ValentSystemvolumePlugin *self)
     238                 :             : {
     239         [ +  + ]:           4 :   if (self->mixer != NULL)
     240                 :             :     {
     241                 :           2 :       g_signal_handlers_disconnect_by_data (self->mixer, self);
     242                 :           2 :       g_ptr_array_remove_range (self->states, 0, self->states->len);
     243         [ +  - ]:           2 :       g_clear_object (&self->mixer);
     244                 :             :     }
     245                 :             : 
     246                 :           4 :   g_object_get (mixer, "primary-adapter", &self->mixer, NULL);
     247         [ +  - ]:           4 :   if (self->mixer != NULL)
     248                 :             :     {
     249                 :           4 :       g_signal_connect_object (self->mixer,
     250                 :             :                                "notify::default-output",
     251                 :             :                                G_CALLBACK (on_default_output_changed),
     252                 :             :                                self,
     253                 :             :                                G_CONNECT_DEFAULT);
     254                 :           4 :       g_signal_connect_object (self->mixer,
     255                 :             :                                "items-changed",
     256                 :             :                                G_CALLBACK (on_items_changed),
     257                 :             :                                self,
     258                 :             :                                G_CONNECT_DEFAULT);
     259                 :           4 :       on_items_changed (G_LIST_MODEL (self->mixer),
     260                 :             :                         0,
     261                 :             :                         0,
     262                 :           4 :                         g_list_model_get_n_items (G_LIST_MODEL (self->mixer)),
     263                 :             :                         self);
     264                 :             :     }
     265                 :           4 : }
     266                 :             : 
     267                 :             : static void
     268                 :          11 : valent_systemvolume_plugin_watch_mixer (ValentSystemvolumePlugin *self,
     269                 :             :                                         gboolean                  watch)
     270                 :             : {
     271                 :          11 :   ValentMixer *mixer = valent_mixer_get_default ();
     272                 :             : 
     273         [ +  - ]:          11 :   g_assert (VALENT_IS_SYSTEMVOLUME_PLUGIN (self));
     274                 :             : 
     275         [ +  + ]:          11 :   if (self->mixer_watch == watch)
     276                 :             :     return;
     277                 :             : 
     278         [ +  + ]:           4 :   if (watch)
     279                 :             :     {
     280                 :           2 :       g_signal_connect_object (mixer,
     281                 :             :                                "notify::default-output",
     282                 :             :                                G_CALLBACK (on_primary_adapter_changed),
     283                 :             :                                self,
     284                 :             :                                G_CONNECT_DEFAULT);
     285                 :           2 :       on_primary_adapter_changed (mixer, NULL, self);
     286                 :             : 
     287         [ +  - ]:           2 :       if (self->adapter == NULL)
     288                 :             :         {
     289                 :           2 :           ValentDevice *device = NULL;
     290                 :             : 
     291                 :           2 :           device = valent_resource_get_source (VALENT_RESOURCE (self));
     292                 :           2 :           self->adapter = valent_systemvolume_device_new (device);
     293                 :           2 :           valent_component_export_adapter (VALENT_COMPONENT (mixer),
     294                 :             :                                            VALENT_EXTENSION (self->adapter));
     295                 :             :         }
     296                 :             :     }
     297                 :             :   else
     298                 :             :     {
     299                 :           2 :       g_signal_handlers_disconnect_by_func (mixer, self, on_primary_adapter_changed);
     300                 :             : 
     301         [ +  - ]:           2 :       if (self->mixer != NULL)
     302                 :             :         {
     303                 :           2 :           g_signal_handlers_disconnect_by_data (self->mixer, self);
     304                 :           2 :           g_ptr_array_remove_range (self->states, 0, self->states->len);
     305         [ +  - ]:           2 :           g_clear_object (&self->mixer);
     306                 :             :         }
     307                 :             : 
     308         [ +  - ]:           2 :       if (self->adapter != NULL)
     309                 :             :         {
     310                 :           2 :           valent_component_unexport_adapter (VALENT_COMPONENT (mixer),
     311                 :             :                                              VALENT_EXTENSION (self->adapter));
     312         [ +  - ]:           2 :           g_clear_object (&self->adapter);
     313                 :             :         }
     314                 :             :     }
     315                 :             : 
     316                 :           4 :   self->mixer_watch = watch;
     317                 :             : }
     318                 :             : 
     319                 :             : /*
     320                 :             :  * Packet Providers
     321                 :             :  */
     322                 :             : static void
     323                 :           8 : valent_systemvolume_plugin_send_sinklist (ValentSystemvolumePlugin *self)
     324                 :             : {
     325                 :          16 :   g_autoptr (JsonBuilder) builder = NULL;
     326         [ -  + ]:           8 :   g_autoptr (JsonNode) packet = NULL;
     327                 :           8 :   unsigned int max_volume = 100;
     328                 :             : 
     329         [ +  - ]:           8 :   g_assert (VALENT_IS_SYSTEMVOLUME_PLUGIN (self));
     330                 :             : 
     331                 :             :   /* Sink List */
     332                 :           8 :   valent_packet_init (&builder, "kdeconnect.systemvolume");
     333                 :           8 :   json_builder_set_member_name (builder, "sinkList");
     334                 :           8 :   json_builder_begin_array (builder);
     335                 :             : 
     336         [ +  + ]:          18 :   for (unsigned int i = 0; i < self->states->len; i++)
     337                 :             :     {
     338                 :          10 :       StreamState *state;
     339                 :             : 
     340                 :          10 :       state = g_ptr_array_index (self->states, i);
     341                 :             : 
     342                 :          10 :       json_builder_begin_object (builder);
     343                 :          10 :       json_builder_set_member_name (builder, "name");
     344                 :          10 :       json_builder_add_string_value (builder, state->name);
     345                 :          10 :       json_builder_set_member_name (builder, "description");
     346                 :          10 :       json_builder_add_string_value (builder, state->description);
     347                 :          10 :       json_builder_set_member_name (builder, "muted");
     348                 :          10 :       json_builder_add_boolean_value (builder, state->muted);
     349                 :          10 :       json_builder_set_member_name (builder, "volume");
     350                 :          10 :       json_builder_add_int_value (builder, state->volume);
     351                 :          10 :       json_builder_set_member_name (builder, "maxVolume");
     352                 :          10 :       json_builder_add_int_value (builder, max_volume);
     353                 :          10 :       json_builder_set_member_name (builder, "enabled");
     354                 :          10 :       json_builder_add_boolean_value (builder, state->enabled);
     355                 :          10 :       json_builder_end_object (builder);
     356                 :             :     }
     357                 :             : 
     358                 :           8 :   json_builder_end_array (builder);
     359                 :           8 :   packet = valent_packet_end (&builder);
     360                 :             : 
     361         [ +  - ]:           8 :   valent_device_plugin_queue_packet (VALENT_DEVICE_PLUGIN (self), packet);
     362                 :           8 : }
     363                 :             : 
     364                 :             : static void
     365                 :           5 : valent_systemvolume_plugin_handle_sink_change (ValentSystemvolumePlugin *self,
     366                 :             :                                                JsonNode                 *packet)
     367                 :             : {
     368                 :           5 :   StreamState *state;
     369                 :           5 :   const char *name;
     370                 :           5 :   int64_t volume;
     371                 :           5 :   gboolean muted;
     372                 :           5 :   gboolean enabled;
     373                 :             : 
     374         [ +  - ]:           5 :   g_assert (VALENT_IS_SYSTEMVOLUME_PLUGIN (self));
     375         [ -  + ]:           5 :   g_assert (VALENT_IS_PACKET (packet));
     376                 :             : 
     377         [ -  + ]:           5 :   if (!valent_packet_get_string (packet, "name", &name))
     378                 :             :     {
     379                 :           0 :       g_debug ("%s(): expected \"name\" field holding a string",
     380                 :             :                G_STRFUNC);
     381                 :           1 :       return;
     382                 :             :     }
     383                 :             : 
     384         [ +  + ]:           5 :   if ((state = stream_state_find (self, name)) == NULL)
     385                 :             :     {
     386                 :           1 :       valent_systemvolume_plugin_send_sinklist (self);
     387                 :           1 :       return;
     388                 :             :     }
     389                 :             : 
     390   [ +  +  +  - ]:           4 :   if (valent_packet_get_int (packet, "volume", &volume) && volume >= 0)
     391                 :           1 :     valent_mixer_stream_set_level (state->stream, volume);
     392                 :             : 
     393         [ +  + ]:           4 :   if (valent_packet_get_boolean (packet, "muted", &muted))
     394                 :           1 :     valent_mixer_stream_set_muted (state->stream, muted);
     395                 :             : 
     396   [ +  +  +  - ]:           4 :   if (valent_packet_get_boolean (packet, "enabled", &enabled) && enabled)
     397                 :           2 :     valent_mixer_adapter_set_default_output (self->mixer, state->stream);
     398                 :             : }
     399                 :             : 
     400                 :             : static void
     401                 :           6 : valent_systemvolume_plugin_handle_request (ValentSystemvolumePlugin *self,
     402                 :             :                                            JsonNode                 *packet)
     403                 :             : {
     404         [ +  - ]:           6 :   g_assert (VALENT_IS_SYSTEMVOLUME_PLUGIN (self));
     405                 :             : 
     406                 :             :   /* A request for a list of audio outputs */
     407         [ +  + ]:           6 :   if (valent_packet_check_field (packet, "requestSinks"))
     408                 :           1 :     valent_systemvolume_plugin_send_sinklist (self);
     409                 :             : 
     410                 :             :   /* A request to change an audio output */
     411         [ +  - ]:           5 :   else if (valent_packet_check_field (packet, "name"))
     412                 :           5 :     valent_systemvolume_plugin_handle_sink_change (self, packet);
     413                 :             : 
     414                 :             :   else
     415                 :           0 :     g_warn_if_reached ();
     416                 :           6 : }
     417                 :             : 
     418                 :             : /*
     419                 :             :  * ValentDevicePlugin
     420                 :             :  */
     421                 :             : static void
     422                 :           7 : valent_systemvolume_plugin_update_state (ValentDevicePlugin *plugin,
     423                 :             :                                          ValentDeviceState   state)
     424                 :             : {
     425                 :           7 :   ValentSystemvolumePlugin *self = VALENT_SYSTEMVOLUME_PLUGIN (plugin);
     426                 :           7 :   gboolean available;
     427                 :             : 
     428         [ +  - ]:           7 :   g_assert (VALENT_IS_SYSTEMVOLUME_PLUGIN (self));
     429                 :             : 
     430                 :           7 :   available = (state & VALENT_DEVICE_STATE_CONNECTED) != 0 &&
     431                 :             :               (state & VALENT_DEVICE_STATE_PAIRED) != 0;
     432                 :             : 
     433                 :             :   /* Watch stream changes */
     434         [ +  + ]:           7 :   if (available)
     435                 :           2 :     valent_systemvolume_plugin_watch_mixer (self, TRUE);
     436                 :             :   else
     437                 :           5 :     valent_systemvolume_plugin_watch_mixer (self, FALSE);
     438                 :           7 : }
     439                 :             : 
     440                 :             : static void
     441                 :          12 : valent_systemvolume_plugin_handle_packet (ValentDevicePlugin *plugin,
     442                 :             :                                           const char         *type,
     443                 :             :                                           JsonNode           *packet)
     444                 :             : {
     445                 :          12 :   ValentSystemvolumePlugin *self = VALENT_SYSTEMVOLUME_PLUGIN (plugin);
     446                 :             : 
     447         [ +  - ]:          12 :   g_assert (VALENT_IS_SYSTEMVOLUME_PLUGIN (self));
     448         [ -  + ]:          12 :   g_assert (type != NULL);
     449         [ -  + ]:          12 :   g_assert (VALENT_IS_PACKET (packet));
     450                 :             : 
     451         [ +  + ]:          12 :   if (g_str_equal (type, "kdeconnect.systemvolume"))
     452                 :           6 :     valent_systemvolume_device_handle_packet (VALENT_SYSTEMVOLUME_DEVICE (self->adapter),
     453                 :             :                                               packet);
     454         [ +  - ]:           6 :   else if (g_str_equal (type, "kdeconnect.systemvolume.request"))
     455                 :           6 :     valent_systemvolume_plugin_handle_request (self, packet);
     456                 :             :   else
     457                 :           0 :     g_assert_not_reached ();
     458                 :          12 : }
     459                 :             : 
     460                 :             : /*
     461                 :             :  * ValentObject
     462                 :             :  */
     463                 :             : static void
     464                 :           4 : valent_systemvolume_plugin_destroy (ValentObject *object)
     465                 :             : {
     466                 :           4 :   ValentSystemvolumePlugin *self = VALENT_SYSTEMVOLUME_PLUGIN (object);
     467                 :             : 
     468                 :           4 :   valent_systemvolume_plugin_watch_mixer (self, FALSE);
     469         [ +  + ]:           4 :   g_clear_pointer (&self->states, g_ptr_array_unref);
     470         [ -  + ]:           4 :   g_clear_object (&self->mixer);
     471                 :             : 
     472                 :           4 :   VALENT_OBJECT_CLASS (valent_systemvolume_plugin_parent_class)->destroy (object);
     473                 :           4 : }
     474                 :             : 
     475                 :             : /*
     476                 :             :  * GObject
     477                 :             :  */
     478                 :             : static void
     479                 :           1 : valent_systemvolume_plugin_class_init (ValentSystemvolumePluginClass *klass)
     480                 :             : {
     481                 :           1 :   ValentObjectClass *vobject_class = VALENT_OBJECT_CLASS (klass);
     482                 :           1 :   ValentDevicePluginClass *plugin_class = VALENT_DEVICE_PLUGIN_CLASS (klass);
     483                 :             : 
     484                 :           1 :   vobject_class->destroy = valent_systemvolume_plugin_destroy;
     485                 :             : 
     486                 :           1 :   plugin_class->handle_packet = valent_systemvolume_plugin_handle_packet;
     487                 :           1 :   plugin_class->update_state = valent_systemvolume_plugin_update_state;
     488                 :             : }
     489                 :             : 
     490                 :             : static void
     491                 :           2 : valent_systemvolume_plugin_init (ValentSystemvolumePlugin *self)
     492                 :             : {
     493                 :           2 :   self->states = g_ptr_array_new_with_free_func (stream_state_free);
     494                 :           2 : }
     495                 :             : 
        

Generated by: LCOV version 2.0-1