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.7 % 227 206
Test Date: 2024-12-02 22:49:30 Functions: 94.7 % 19 18
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 60.9 % 138 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 :   g_assert (VALENT_IS_SYSTEMVOLUME_PLUGIN (self));
     272                 :             : 
     273         [ +  + ]:          11 :   if (self->mixer_watch == watch)
     274                 :             :     return;
     275                 :             : 
     276         [ +  + ]:           4 :   if (watch)
     277                 :             :     {
     278                 :           2 :       g_signal_connect_object (valent_mixer_get_default (),
     279                 :             :                                "notify::default-output",
     280                 :             :                                G_CALLBACK (on_primary_adapter_changed),
     281                 :             :                                self,
     282                 :             :                                G_CONNECT_DEFAULT);
     283                 :           2 :       on_primary_adapter_changed (valent_mixer_get_default (), NULL, self);
     284                 :             :     }
     285                 :             :   else
     286                 :             :     {
     287                 :           2 :       g_signal_handlers_disconnect_by_data (valent_mixer_get_default (), self);
     288                 :             : 
     289         [ +  - ]:           2 :       if (self->mixer != NULL)
     290                 :             :         {
     291                 :           2 :           g_signal_handlers_disconnect_by_data (self->mixer, self);
     292                 :           2 :           g_ptr_array_remove_range (self->states, 0, self->states->len);
     293         [ +  - ]:           2 :           g_clear_object (&self->mixer);
     294                 :             :         }
     295                 :             :     }
     296                 :             : 
     297                 :           4 :   self->mixer_watch = watch;
     298                 :             : }
     299                 :             : 
     300                 :             : /*
     301                 :             :  * Packet Providers
     302                 :             :  */
     303                 :             : static void
     304                 :           8 : valent_systemvolume_plugin_send_sinklist (ValentSystemvolumePlugin *self)
     305                 :             : {
     306                 :          16 :   g_autoptr (JsonBuilder) builder = NULL;
     307         [ -  + ]:           8 :   g_autoptr (JsonNode) packet = NULL;
     308                 :           8 :   unsigned int max_volume = 100;
     309                 :             : 
     310         [ +  - ]:           8 :   g_assert (VALENT_IS_SYSTEMVOLUME_PLUGIN (self));
     311                 :             : 
     312                 :             :   /* Sink List */
     313                 :           8 :   valent_packet_init (&builder, "kdeconnect.systemvolume");
     314                 :           8 :   json_builder_set_member_name (builder, "sinkList");
     315                 :           8 :   json_builder_begin_array (builder);
     316                 :             : 
     317         [ +  + ]:          18 :   for (unsigned int i = 0; i < self->states->len; i++)
     318                 :             :     {
     319                 :          10 :       StreamState *state;
     320                 :             : 
     321                 :          10 :       state = g_ptr_array_index (self->states, i);
     322                 :             : 
     323                 :          10 :       json_builder_begin_object (builder);
     324                 :          10 :       json_builder_set_member_name (builder, "name");
     325                 :          10 :       json_builder_add_string_value (builder, state->name);
     326                 :          10 :       json_builder_set_member_name (builder, "description");
     327                 :          10 :       json_builder_add_string_value (builder, state->description);
     328                 :          10 :       json_builder_set_member_name (builder, "muted");
     329                 :          10 :       json_builder_add_boolean_value (builder, state->muted);
     330                 :          10 :       json_builder_set_member_name (builder, "volume");
     331                 :          10 :       json_builder_add_int_value (builder, state->volume);
     332                 :          10 :       json_builder_set_member_name (builder, "maxVolume");
     333                 :          10 :       json_builder_add_int_value (builder, max_volume);
     334                 :          10 :       json_builder_set_member_name (builder, "enabled");
     335                 :          10 :       json_builder_add_boolean_value (builder, state->enabled);
     336                 :          10 :       json_builder_end_object (builder);
     337                 :             :     }
     338                 :             : 
     339                 :           8 :   json_builder_end_array (builder);
     340                 :           8 :   packet = valent_packet_end (&builder);
     341                 :             : 
     342         [ +  - ]:           8 :   valent_device_plugin_queue_packet (VALENT_DEVICE_PLUGIN (self), packet);
     343                 :           8 : }
     344                 :             : 
     345                 :             : static void
     346                 :           5 : valent_systemvolume_plugin_handle_sink_change (ValentSystemvolumePlugin *self,
     347                 :             :                                                JsonNode                 *packet)
     348                 :             : {
     349                 :           5 :   StreamState *state;
     350                 :           5 :   const char *name;
     351                 :           5 :   int64_t volume;
     352                 :           5 :   gboolean muted;
     353                 :           5 :   gboolean enabled;
     354                 :             : 
     355         [ +  - ]:           5 :   g_assert (VALENT_IS_SYSTEMVOLUME_PLUGIN (self));
     356         [ -  + ]:           5 :   g_assert (VALENT_IS_PACKET (packet));
     357                 :             : 
     358         [ -  + ]:           5 :   if (!valent_packet_get_string (packet, "name", &name))
     359                 :             :     {
     360                 :           0 :       g_debug ("%s(): expected \"name\" field holding a string",
     361                 :             :                G_STRFUNC);
     362                 :           1 :       return;
     363                 :             :     }
     364                 :             : 
     365         [ +  + ]:           5 :   if ((state = stream_state_find (self, name)) == NULL)
     366                 :             :     {
     367                 :           1 :       valent_systemvolume_plugin_send_sinklist (self);
     368                 :           1 :       return;
     369                 :             :     }
     370                 :             : 
     371   [ +  +  +  - ]:           4 :   if (valent_packet_get_int (packet, "volume", &volume) && volume >= 0)
     372                 :           1 :     valent_mixer_stream_set_level (state->stream, volume);
     373                 :             : 
     374         [ +  + ]:           4 :   if (valent_packet_get_boolean (packet, "muted", &muted))
     375                 :           1 :     valent_mixer_stream_set_muted (state->stream, muted);
     376                 :             : 
     377   [ +  +  +  - ]:           4 :   if (valent_packet_get_boolean (packet, "enabled", &enabled) && enabled)
     378                 :           2 :     valent_mixer_adapter_set_default_output (self->mixer, state->stream);
     379                 :             : }
     380                 :             : 
     381                 :             : static void
     382                 :           6 : valent_systemvolume_plugin_handle_request (ValentSystemvolumePlugin *self,
     383                 :             :                                            JsonNode                 *packet)
     384                 :             : {
     385         [ +  - ]:           6 :   g_assert (VALENT_IS_SYSTEMVOLUME_PLUGIN (self));
     386                 :             : 
     387                 :             :   /* A request for a list of audio outputs */
     388         [ +  + ]:           6 :   if (valent_packet_check_field (packet, "requestSinks"))
     389                 :           1 :     valent_systemvolume_plugin_send_sinklist (self);
     390                 :             : 
     391                 :             :   /* A request to change an audio output */
     392         [ +  - ]:           5 :   else if (valent_packet_check_field (packet, "name"))
     393                 :           5 :     valent_systemvolume_plugin_handle_sink_change (self, packet);
     394                 :             : 
     395                 :             :   else
     396                 :           0 :     g_warn_if_reached ();
     397                 :           6 : }
     398                 :             : 
     399                 :             : /*
     400                 :             :  * ValentDevicePlugin
     401                 :             :  */
     402                 :             : static void
     403                 :           7 : valent_systemvolume_plugin_update_state (ValentDevicePlugin *plugin,
     404                 :             :                                          ValentDeviceState   state)
     405                 :             : {
     406                 :           7 :   ValentSystemvolumePlugin *self = VALENT_SYSTEMVOLUME_PLUGIN (plugin);
     407                 :           7 :   gboolean available;
     408                 :             : 
     409         [ +  - ]:           7 :   g_assert (VALENT_IS_SYSTEMVOLUME_PLUGIN (self));
     410                 :             : 
     411                 :           7 :   available = (state & VALENT_DEVICE_STATE_CONNECTED) != 0 &&
     412                 :             :               (state & VALENT_DEVICE_STATE_PAIRED) != 0;
     413                 :             : 
     414                 :             :   /* Watch stream changes */
     415         [ +  + ]:           7 :   if (available)
     416                 :           2 :     valent_systemvolume_plugin_watch_mixer (self, TRUE);
     417                 :             :   else
     418                 :           5 :     valent_systemvolume_plugin_watch_mixer (self, FALSE);
     419                 :           7 : }
     420                 :             : 
     421                 :             : static void
     422                 :          12 : valent_systemvolume_plugin_handle_packet (ValentDevicePlugin *plugin,
     423                 :             :                                           const char         *type,
     424                 :             :                                           JsonNode           *packet)
     425                 :             : {
     426                 :          12 :   ValentSystemvolumePlugin *self = VALENT_SYSTEMVOLUME_PLUGIN (plugin);
     427                 :             : 
     428         [ +  - ]:          12 :   g_assert (VALENT_IS_SYSTEMVOLUME_PLUGIN (self));
     429         [ -  + ]:          12 :   g_assert (type != NULL);
     430         [ -  + ]:          12 :   g_assert (VALENT_IS_PACKET (packet));
     431                 :             : 
     432         [ +  + ]:          12 :   if (g_str_equal (type, "kdeconnect.systemvolume"))
     433                 :           6 :     valent_systemvolume_device_handle_packet (VALENT_SYSTEMVOLUME_DEVICE (self->adapter),
     434                 :             :                                               packet);
     435         [ +  - ]:           6 :   else if (g_str_equal (type, "kdeconnect.systemvolume.request"))
     436                 :           6 :     valent_systemvolume_plugin_handle_request (self, packet);
     437                 :             :   else
     438                 :           0 :     g_assert_not_reached ();
     439                 :          12 : }
     440                 :             : 
     441                 :             : /*
     442                 :             :  * ValentObject
     443                 :             :  */
     444                 :             : static void
     445                 :           4 : valent_systemvolume_plugin_destroy (ValentObject *object)
     446                 :             : {
     447                 :           4 :   ValentSystemvolumePlugin *self = VALENT_SYSTEMVOLUME_PLUGIN (object);
     448                 :           4 :   ValentComponent *component = NULL;
     449                 :             : 
     450         [ +  + ]:           4 :   if (self->adapter != NULL)
     451                 :             :     {
     452                 :           2 :       component = VALENT_COMPONENT (valent_mixer_get_default ());
     453                 :           2 :       valent_component_unexport_adapter (component, VALENT_EXTENSION (self->adapter));
     454                 :           2 :       valent_object_destroy (VALENT_OBJECT (self->adapter));
     455         [ +  - ]:           2 :       g_clear_object (&self->adapter);
     456                 :             :     }
     457                 :             : 
     458                 :           4 :   valent_systemvolume_plugin_watch_mixer (self, FALSE);
     459         [ +  + ]:           4 :   g_clear_pointer (&self->states, g_ptr_array_unref);
     460         [ -  + ]:           4 :   g_clear_object (&self->mixer);
     461                 :             : 
     462                 :           4 :   VALENT_OBJECT_CLASS (valent_systemvolume_plugin_parent_class)->destroy (object);
     463                 :           4 : }
     464                 :             : 
     465                 :             : /*
     466                 :             :  * GObject
     467                 :             :  */
     468                 :             : static void
     469                 :           2 : valent_systemvolume_plugin_constructed (GObject *object)
     470                 :             : {
     471                 :           2 :   ValentSystemvolumePlugin *self = VALENT_SYSTEMVOLUME_PLUGIN (object);
     472                 :           2 :   ValentComponent *component = NULL;
     473                 :           2 :   ValentDevice *device = NULL;
     474                 :             : 
     475                 :           2 :   G_OBJECT_CLASS (valent_systemvolume_plugin_parent_class)->constructed (object);
     476                 :             : 
     477                 :           2 :   device = valent_extension_get_object (VALENT_EXTENSION (self));
     478                 :           2 :   self->adapter = valent_systemvolume_device_new (device);
     479                 :           2 :   component = VALENT_COMPONENT (valent_mixer_get_default ());
     480                 :           2 :   valent_component_export_adapter (component, VALENT_EXTENSION (self->adapter));
     481                 :           2 : }
     482                 :             : 
     483                 :             : static void
     484                 :           1 : valent_systemvolume_plugin_class_init (ValentSystemvolumePluginClass *klass)
     485                 :             : {
     486                 :           1 :   GObjectClass *object_class = G_OBJECT_CLASS (klass);
     487                 :           1 :   ValentObjectClass *vobject_class = VALENT_OBJECT_CLASS (klass);
     488                 :           1 :   ValentDevicePluginClass *plugin_class = VALENT_DEVICE_PLUGIN_CLASS (klass);
     489                 :             : 
     490                 :           1 :   object_class->constructed = valent_systemvolume_plugin_constructed;
     491                 :             : 
     492                 :           1 :   vobject_class->destroy = valent_systemvolume_plugin_destroy;
     493                 :             : 
     494                 :           1 :   plugin_class->handle_packet = valent_systemvolume_plugin_handle_packet;
     495                 :           1 :   plugin_class->update_state = valent_systemvolume_plugin_update_state;
     496                 :             : }
     497                 :             : 
     498                 :             : static void
     499                 :           2 : valent_systemvolume_plugin_init (ValentSystemvolumePlugin *self)
     500                 :             : {
     501                 :           2 :   self->states = g_ptr_array_new_with_free_func (stream_state_free);
     502                 :           2 : }
     503                 :             : 
        

Generated by: LCOV version 2.0-1