LCOV - code coverage report
Current view: top level - src/plugins/findmyphone - valent-findmyphone-ringer.c (source / functions) Coverage Total Hit
Test: Code Coverage Lines: 29.8 % 94 28
Test Date: 2024-12-21 23:29:11 Functions: 41.7 % 12 5
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 13.6 % 66 9

             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-findmyphone-plugin"
       5                 :             : 
       6                 :             : #include "config.h"
       7                 :             : 
       8                 :             : #include <gio/gio.h>
       9                 :             : #include <glib/gi18n.h>
      10                 :             : #include <gst/gst.h>
      11                 :             : 
      12                 :             : #include "valent-findmyphone-ringer.h"
      13                 :             : 
      14                 :             : 
      15                 :             : struct _ValentFindmyphoneRinger
      16                 :             : {
      17                 :             :   GActionGroup  *actions;
      18                 :             :   GNotification *notification;
      19                 :             :   GstElement    *playbin;
      20                 :             :   unsigned int   source_id;
      21                 :             :   gpointer       owner;
      22                 :             : };
      23                 :             : 
      24                 :             : static ValentFindmyphoneRinger *default_ringer = NULL;
      25                 :             : 
      26                 :             : 
      27                 :             : static gboolean
      28                 :           0 : ringer_source_func (GstBus     *bus,
      29                 :             :                     GstMessage *message,
      30                 :             :                     gpointer    user_data)
      31                 :             : {
      32                 :           0 :   ValentFindmyphoneRinger *ringer = user_data;
      33                 :             : 
      34         [ #  # ]:           0 :   if (message->type == GST_MESSAGE_ERROR)
      35                 :             :     {
      36                 :           0 :       g_autoptr (GError) error = NULL;
      37         [ #  # ]:           0 :       g_autofree char *debug = NULL;
      38                 :             : 
      39                 :           0 :       gst_message_parse_error (message, &error, &debug);
      40                 :           0 :       g_warning ("%s(): %s", G_STRFUNC, error->message);
      41         [ #  # ]:           0 :       g_debug ("%s: %s", G_STRFUNC, (debug) ? debug : "none");
      42                 :             : 
      43                 :           0 :       return G_SOURCE_REMOVE;
      44                 :             :     }
      45                 :             : 
      46                 :             :   /* Rewind to beginning */
      47         [ #  # ]:           0 :   if (message->type == GST_MESSAGE_EOS)
      48                 :             :     {
      49                 :           0 :       return gst_element_seek_simple (ringer->playbin,
      50                 :             :                                       GST_FORMAT_TIME,
      51                 :             :                                       GST_SEEK_FLAG_FLUSH,
      52                 :             :                                       0);
      53                 :             :     }
      54                 :             : 
      55                 :             :   return G_SOURCE_CONTINUE;
      56                 :             : }
      57                 :             : 
      58                 :             : static inline void
      59                 :           0 : app_ringer_action (GSimpleAction *action,
      60                 :             :                    GVariant      *parameters,
      61                 :             :                    gpointer       user_data)
      62                 :             : {
      63                 :           0 :   ValentFindmyphoneRinger *self = (ValentFindmyphoneRinger *)user_data;
      64                 :             : 
      65         [ #  # ]:           0 :   g_assert (self != NULL);
      66                 :             : 
      67                 :           0 :   valent_findmyphone_ringer_toggle (self, NULL);
      68                 :           0 : }
      69                 :             : 
      70                 :             : static const GActionEntry app_actions[] = {
      71                 :             :   { "ringer", app_ringer_action, NULL, NULL, NULL },
      72                 :             : };
      73                 :             : 
      74                 :             : static void
      75                 :           4 : valent_findmyphone_ringer_free (gpointer data)
      76                 :             : {
      77                 :           4 :   ValentFindmyphoneRinger *ringer = data;
      78                 :             : 
      79         [ -  + ]:           4 :   if (ringer->notification != NULL)
      80                 :             :     {
      81                 :           0 :       GApplication *application = g_application_get_default ();
      82                 :             : 
      83                 :           0 :       g_action_map_remove_action (G_ACTION_MAP (application), "ringer");
      84                 :           0 :       g_application_withdraw_notification (application, "findmyphone::ringer");
      85         [ #  # ]:           0 :       g_clear_object (&ringer->notification);
      86                 :             :     }
      87                 :             : 
      88         [ -  + ]:           4 :   if (ringer->playbin != NULL)
      89                 :             :     {
      90                 :           0 :       gst_element_set_state (ringer->playbin, GST_STATE_NULL);
      91         [ #  # ]:           0 :       gst_clear_object (&ringer->playbin);
      92                 :             :     }
      93                 :             : 
      94                 :           4 :   default_ringer = NULL;
      95                 :           4 : }
      96                 :             : 
      97                 :             : /**
      98                 :             :  * valent_findmyphone_ringer_new:
      99                 :             :  *
     100                 :             :  * Create a new `ValentFindmyphoneRinger`.
     101                 :             :  *
     102                 :             :  * Returns: (transfer full): a `ValentFindmyphoneRinger`
     103                 :             :  */
     104                 :             : ValentFindmyphoneRinger *
     105                 :           4 : valent_findmyphone_ringer_new (void)
     106                 :             : {
     107                 :           4 :   GApplication *application = g_application_get_default ();
     108                 :           4 :   ValentFindmyphoneRinger *ringer;
     109                 :           8 :   g_autoptr (GError) error = NULL;
     110                 :             : 
     111                 :           4 :   ringer = g_rc_box_new0 (ValentFindmyphoneRinger);
     112                 :             : 
     113                 :             :   /* Notification
     114                 :             :    */
     115         [ -  + ]:           4 :   if (application != NULL)
     116                 :             :     {
     117                 :           4 :       g_autoptr (GIcon) icon = NULL;
     118                 :             : 
     119                 :           0 :       g_action_map_add_action_entries (G_ACTION_MAP (application),
     120                 :             :                                        app_actions,
     121                 :             :                                        G_N_ELEMENTS (app_actions),
     122                 :             :                                        ringer);
     123                 :           0 :       icon = g_icon_new_for_string ("phonelink-ring-symbolic", NULL);
     124                 :             : 
     125                 :           0 :       ringer->notification = g_notification_new (_("Find My Device"));
     126                 :           0 :       g_notification_set_icon (ringer->notification, icon);
     127                 :           0 :       g_notification_set_priority (ringer->notification,
     128                 :             :                                    G_NOTIFICATION_PRIORITY_URGENT);
     129         [ #  # ]:           0 :       g_notification_set_default_action (ringer->notification, "app.ringer");
     130                 :             :     }
     131                 :             : 
     132                 :             :   /* Playbin
     133                 :             :    */
     134         [ -  + ]:           4 :   if (!gst_init_check (NULL, NULL, &error))
     135                 :             :     {
     136                 :           0 :       g_warning ("%s(): %s", G_STRFUNC, error->message);
     137                 :           0 :       return ringer;
     138                 :             :     }
     139                 :             : 
     140                 :           4 :   ringer->playbin = gst_element_factory_make ("playbin", "findmyphone-ringer");
     141         [ -  + ]:           4 :   if (ringer->playbin != NULL)
     142                 :             :     {
     143                 :           0 :       gst_object_ref_sink (ringer->playbin);
     144                 :           0 :       g_object_set (ringer->playbin,
     145                 :             :                     "uri", "resource:///plugins/findmyphone/alert.oga",
     146                 :             :                     NULL);
     147                 :             :     }
     148                 :             : 
     149                 :             :   return ringer;
     150                 :             : }
     151                 :             : 
     152                 :             : /**
     153                 :             :  * valent_findmyphone_ringer_start:
     154                 :             :  * @ringer: a `ValentFindmyphoneRinger`
     155                 :             :  *
     156                 :             :  * Enable the ringing state of @ringer.
     157                 :             :  */
     158                 :             : void
     159                 :           0 : valent_findmyphone_ringer_start (ValentFindmyphoneRinger *ringer)
     160                 :             : {
     161                 :           0 :   g_autoptr (GstBus) playbus = NULL;
     162                 :             : 
     163         [ #  # ]:           0 :   g_return_if_fail (ringer != NULL);
     164                 :             : 
     165   [ #  #  #  # ]:           0 :   if (ringer->playbin == NULL || ringer->source_id > 0)
     166                 :             :     return;
     167                 :             : 
     168                 :           0 :   playbus = gst_element_get_bus (ringer->playbin);
     169                 :           0 :   ringer->source_id = gst_bus_add_watch (playbus, ringer_source_func, ringer);
     170                 :             : 
     171         [ #  # ]:           0 :   if (gst_element_set_state (ringer->playbin, GST_STATE_PLAYING) == 0)
     172   [ #  #  #  # ]:           0 :     g_clear_handle_id (&ringer->source_id, g_source_remove);
     173                 :             : }
     174                 :             : 
     175                 :             : /**
     176                 :             :  * valent_findmyphone_ringer_stop:
     177                 :             :  * @ringer: a `ValentFindmyphoneRinger`
     178                 :             :  *
     179                 :             :  * Disable the ringing state of @ringer.
     180                 :             :  */
     181                 :             : void
     182                 :           0 : valent_findmyphone_ringer_stop (ValentFindmyphoneRinger *ringer)
     183                 :             : {
     184         [ #  # ]:           0 :   g_return_if_fail (ringer != NULL);
     185                 :             : 
     186   [ #  #  #  # ]:           0 :   if (ringer->playbin == NULL || ringer->source_id == 0)
     187                 :             :     return;
     188                 :             : 
     189                 :           0 :   gst_element_set_state (ringer->playbin, GST_STATE_NULL);
     190         [ #  # ]:           0 :   g_clear_handle_id (&ringer->source_id, g_source_remove);
     191                 :           0 :   ringer->owner = NULL;
     192                 :             : }
     193                 :             : 
     194                 :             : /**
     195                 :             :  * valent_findmyphone_ringer_show:
     196                 :             :  * @ringer: a `ValentFindmyphoneRinger`
     197                 :             :  *
     198                 :             :  * Enable the ringing state of @ringer and show a dialog.
     199                 :             :  */
     200                 :             : void
     201                 :           0 : valent_findmyphone_ringer_show (ValentFindmyphoneRinger *ringer)
     202                 :             : {
     203                 :           0 :   GApplication *application = g_application_get_default ();
     204                 :             : 
     205         [ #  # ]:           0 :   g_return_if_fail (ringer != NULL);
     206                 :             : 
     207                 :           0 :   valent_findmyphone_ringer_start (ringer);
     208         [ #  # ]:           0 :   if (application != NULL)
     209                 :             :     {
     210                 :           0 :       g_application_send_notification (application,
     211                 :             :                                        "findmyphone::ringer",
     212                 :             :                                        ringer->notification);
     213                 :             :     }
     214                 :             : }
     215                 :             : 
     216                 :             : /**
     217                 :             :  * valent_findmyphone_ringer_hide:
     218                 :             :  * @ringer: a `ValentFindmyphoneRinger`
     219                 :             :  *
     220                 :             :  * Disable the ringing state of @ringer and hide the dialog.
     221                 :             :  */
     222                 :             : void
     223                 :           0 : valent_findmyphone_ringer_hide (ValentFindmyphoneRinger *ringer)
     224                 :             : {
     225                 :           0 :   GApplication *application = g_application_get_default ();
     226                 :             : 
     227         [ #  # ]:           0 :   g_return_if_fail (ringer != NULL);
     228                 :             : 
     229         [ #  # ]:           0 :   if (ringer->notification != NULL)
     230                 :           0 :     g_application_withdraw_notification (application, "findmyphone::ringer");
     231                 :             : 
     232                 :           0 :   valent_findmyphone_ringer_stop (ringer);
     233                 :             : }
     234                 :             : 
     235                 :             : /**
     236                 :             :  * valent_findmyphone_ringer_acquire:
     237                 :             :  *
     238                 :             :  * Acquire a reference on the default `ValentFindmyphoneRinger`.
     239                 :             :  *
     240                 :             :  * Returns: (transfer full): a `ValentFindmyphoneRinger`
     241                 :             :  */
     242                 :             : ValentFindmyphoneRinger *
     243                 :           4 : valent_findmyphone_ringer_acquire (void)
     244                 :             : {
     245         [ +  - ]:           4 :   if (default_ringer == NULL)
     246                 :             :     {
     247                 :           4 :       default_ringer = valent_findmyphone_ringer_new ();
     248                 :           4 :       return default_ringer;
     249                 :             :     }
     250                 :             : 
     251                 :           0 :   return g_rc_box_acquire (default_ringer);
     252                 :             : }
     253                 :             : 
     254                 :             : /**
     255                 :             :  * valent_findmyphone_ringer_release:
     256                 :             :  * @data: (type Valent.FindmyphoneRinger): a `ValentFindmyphoneRinger`
     257                 :             :  *
     258                 :             :  * Release a reference on the default `ValentFindmyphoneRinger`.
     259                 :             :  */
     260                 :             : void
     261                 :           4 : valent_findmyphone_ringer_release (gpointer data)
     262                 :             : {
     263                 :           4 :   ValentFindmyphoneRinger *ringer = data;
     264                 :             : 
     265         [ +  - ]:           4 :   g_return_if_fail (ringer != NULL);
     266                 :             : 
     267                 :           4 :   g_rc_box_release_full (ringer, valent_findmyphone_ringer_free);
     268                 :             : }
     269                 :             : 
     270                 :             : /**
     271                 :             :  * valent_findmyphone_ringer_toggle:
     272                 :             :  * @ringer: a `ValentFindmyphoneRinger`
     273                 :             :  * @owner: (type GObject.Object): a `GObject`
     274                 :             :  *
     275                 :             :  * Toggle the ringing state of @ringer.
     276                 :             :  */
     277                 :             : void
     278                 :           0 : valent_findmyphone_ringer_toggle (ValentFindmyphoneRinger *ringer,
     279                 :             :                                   gpointer                 owner)
     280                 :             : {
     281         [ #  # ]:           0 :   g_return_if_fail (ringer != NULL);
     282                 :             : 
     283         [ #  # ]:           0 :   if (ringer->source_id > 0)
     284                 :             :     {
     285                 :           0 :       valent_findmyphone_ringer_hide (ringer);
     286                 :           0 :       ringer->owner = NULL;
     287                 :             :     }
     288                 :             :   else
     289                 :             :     {
     290                 :           0 :       valent_findmyphone_ringer_show (ringer);
     291                 :           0 :       ringer->owner = owner;
     292                 :             :     }
     293                 :             : }
     294                 :             : 
     295                 :             : /**
     296                 :             :  * valent_findmyphone_ringer_is_owner:
     297                 :             :  * @ringer: a `ValentFindmyphoneRinger`
     298                 :             :  * @owner: (type GObject.Object): a `GObject`
     299                 :             :  *
     300                 :             :  * Check if @owner is responsible for the current state of @ringer.
     301                 :             :  *
     302                 :             :  * Returns: %TRUE if @owner controls the ringer
     303                 :             :  */
     304                 :             : gboolean
     305                 :           7 : valent_findmyphone_ringer_is_owner (ValentFindmyphoneRinger *ringer,
     306                 :             :                                     gpointer                 owner)
     307                 :             : {
     308         [ +  - ]:           7 :   g_return_val_if_fail (ringer != NULL, FALSE);
     309         [ -  + ]:           7 :   g_return_val_if_fail (G_IS_OBJECT (owner), FALSE);
     310                 :             : 
     311                 :           7 :   return ringer->owner == owner;
     312                 :             : }
     313                 :             : 
        

Generated by: LCOV version 2.0-1