LCOV - code coverage report
Current view: top level - src/plugins/sms - valent-sms-plugin.c (source / functions) Coverage Total Hit
Test: Code Coverage Lines: 81.5 % 238 194
Test Date: 2024-03-22 06:22:29 Functions: 90.0 % 20 18
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 46.9 % 130 61

             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-sms-plugin"
       5                 :             : 
       6                 :             : #include "config.h"
       7                 :             : 
       8                 :             : #include <glib/gi18n.h>
       9                 :             : #include <gio/gio.h>
      10                 :             : #include <json-glib/json-glib.h>
      11                 :             : #include <valent.h>
      12                 :             : 
      13                 :             : #include "valent-message.h"
      14                 :             : #include "valent-sms-plugin.h"
      15                 :             : #include "valent-sms-store.h"
      16                 :             : #include "valent-sms-window.h"
      17                 :             : 
      18                 :             : 
      19                 :             : struct _ValentSmsPlugin
      20                 :             : {
      21                 :             :   ValentDevicePlugin  parent_instance;
      22                 :             : 
      23                 :             :   ValentSmsStore    *store;
      24                 :             :   GtkWindow         *window;
      25                 :             : };
      26                 :             : 
      27                 :             : static ValentMessage * valent_sms_plugin_deserialize_message   (ValentSmsPlugin *self,
      28                 :             :                                                                 JsonNode        *node);
      29                 :             : static void            valent_sms_plugin_request               (ValentSmsPlugin *self,
      30                 :             :                                                                 ValentMessage   *message);
      31                 :             : static void            valent_sms_plugin_request_conversation  (ValentSmsPlugin *self,
      32                 :             :                                                                 int64_t          thread_id,
      33                 :             :                                                                 int64_t          start_date,
      34                 :             :                                                                 int64_t          max_results);
      35                 :             : static void            valent_sms_plugin_request_conversations (ValentSmsPlugin *self);
      36                 :             : 
      37   [ +  +  +  - ]:          41 : G_DEFINE_FINAL_TYPE (ValentSmsPlugin, valent_sms_plugin, VALENT_TYPE_DEVICE_PLUGIN)
      38                 :             : 
      39                 :             : 
      40                 :             : /**
      41                 :             :  * message_hash:
      42                 :             :  * @message_id: a message ID
      43                 :             :  * @message_text: (nullable): a message text
      44                 :             :  *
      45                 :             :  * Shift the lower 32-bits of @message_id to the upper 32-bits of a 64-bit
      46                 :             :  * integer, then set the lower 32-bits to a djb2 hash of @message_text.
      47                 :             :  *
      48                 :             :  * This hack is necessary because kdeconnect-android pulls SMS and MMS from
      49                 :             :  * separate tables so two messages (even in the same thread) may share an ID.
      50                 :             :  * The timestamp would be an ideal alternative except that it can change,
      51                 :             :  * possibly when moved between boxes (eg. outbox => sent).
      52                 :             :  *
      53                 :             :  * Returns: a unique ID
      54                 :             :  */
      55                 :             : static inline int64_t
      56                 :           3 : message_hash (int64_t     message_id,
      57                 :             :               const char *message_text)
      58                 :             : {
      59                 :           3 :   uint32_t hash = 5381;
      60                 :             : 
      61         [ +  - ]:           3 :   if G_UNLIKELY (message_text == NULL)
      62                 :             :     message_text = "";
      63                 :             : 
      64                 :             :   // djb2
      65         [ +  + ]:          52 :   for (unsigned int i = 0; message_text[i]; i++)
      66                 :          49 :     hash = ((hash << 5L) + hash) + message_text[i]; /* hash * 33 + c */
      67                 :             : 
      68                 :           3 :   return (((uint64_t) message_id) << 32) | hash;
      69                 :             : }
      70                 :             : 
      71                 :             : static ValentMessage *
      72                 :           3 : valent_sms_plugin_deserialize_message (ValentSmsPlugin *self,
      73                 :             :                                        JsonNode        *node)
      74                 :             : {
      75                 :           3 :   JsonObject *object;
      76                 :           3 :   JsonNode *addr_node;
      77                 :           3 :   GVariant *addresses;
      78                 :           3 :   GVariantDict dict;
      79                 :             : 
      80                 :           3 :   ValentMessageBox box;
      81                 :           3 :   int64_t date;
      82                 :           3 :   int64_t id;
      83                 :           3 :   GVariant *metadata;
      84                 :           3 :   int64_t read;
      85                 :           3 :   const char *sender = NULL;
      86                 :           3 :   const char *text = NULL;
      87                 :           3 :   int64_t thread_id;
      88                 :           3 :   ValentMessageFlags event = VALENT_MESSAGE_FLAGS_UNKNOWN;
      89                 :           3 :   int64_t sub_id = -1;
      90                 :             : 
      91         [ +  - ]:           3 :   g_assert (VALENT_IS_SMS_PLUGIN (self));
      92         [ -  + ]:           3 :   g_assert (JSON_NODE_HOLDS_OBJECT (node));
      93                 :             : 
      94                 :           3 :   object = json_node_get_object (node);
      95                 :             : 
      96                 :             :   /* Check all the required fields exist */
      97   [ +  -  +  -  :           3 :   if G_UNLIKELY (!json_object_has_member (object, "thread_id") ||
          +  -  +  -  +  
             -  +  -  +  
                      - ]
      98                 :             :                  !json_object_has_member (object, "_id") ||
      99                 :             :                  !json_object_has_member (object, "body") ||
     100                 :             :                  !json_object_has_member (object, "date") ||
     101                 :             :                  !json_object_has_member (object, "read") ||
     102                 :             :                  !json_object_has_member (object, "type") ||
     103                 :             :                  !json_object_has_member (object, "addresses"))
     104                 :             :     {
     105                 :           0 :       g_warning ("%s(): missing required message field", G_STRFUNC);
     106                 :           0 :       return NULL;
     107                 :             :     }
     108                 :             : 
     109                 :             :   /* Basic fields */
     110                 :           3 :   box = json_object_get_int_member (object, "type");
     111                 :           3 :   date = json_object_get_int_member (object, "date");
     112                 :           3 :   id = json_object_get_int_member (object, "_id");
     113                 :           3 :   read = json_object_get_int_member (object, "read");
     114                 :           3 :   text = json_object_get_string_member (object, "body");
     115                 :           3 :   thread_id = json_object_get_int_member (object, "thread_id");
     116                 :             : 
     117                 :             :   /* Addresses */
     118                 :           3 :   addr_node = json_object_get_member (object, "addresses");
     119                 :           3 :   addresses = json_gvariant_deserialize (addr_node, "aa{sv}", NULL);
     120                 :             : 
     121                 :             :   /* If incoming, the first address will be the sender */
     122         [ +  + ]:           3 :   if (box == VALENT_MESSAGE_BOX_INBOX)
     123                 :             :     {
     124                 :           1 :       JsonObject *sender_obj;
     125                 :           1 :       JsonArray *addr_array;
     126                 :             : 
     127                 :           1 :       addr_array = json_node_get_array (addr_node);
     128                 :             : 
     129         [ +  - ]:           1 :       if (json_array_get_length (addr_array) > 0)
     130                 :             :         {
     131                 :           1 :           sender_obj = json_array_get_object_element (addr_array, 0);
     132                 :           1 :           sender = json_object_get_string_member (sender_obj, "address");
     133                 :             :         }
     134                 :             :       else
     135                 :           0 :         g_warning ("No address for message %"G_GINT64_FORMAT" in thread %"G_GINT64_FORMAT, id, thread_id);
     136                 :             :     }
     137                 :             : 
     138                 :             :   /* TODO: The `event` and `sub_id` fields are currently not implemented */
     139         [ +  - ]:           3 :   if (json_object_has_member (object, "event"))
     140                 :           3 :     event = json_object_get_int_member (object, "event");
     141                 :             : 
     142         [ +  - ]:           3 :   if (json_object_has_member (object, "sub_id"))
     143                 :           3 :     sub_id = json_object_get_int_member (object, "sub_id");
     144                 :             : 
     145                 :             :   /* HACK: try to create a truly unique ID from a potentially non-unique ID */
     146                 :           3 :   id = message_hash (id, text);
     147                 :             : 
     148                 :             :   /* Build the metadata dictionary */
     149                 :           3 :   g_variant_dict_init (&dict, NULL);
     150                 :           3 :   g_variant_dict_insert_value (&dict, "addresses", addresses);
     151                 :           3 :   g_variant_dict_insert (&dict, "event", "u", event);
     152                 :           3 :   g_variant_dict_insert (&dict, "sub_id", "i", sub_id);
     153                 :           3 :   metadata = g_variant_dict_end (&dict);
     154                 :             : 
     155                 :             :   /* Build and return the message object */
     156                 :           3 :   return g_object_new (VALENT_TYPE_MESSAGE,
     157                 :             :                        "box",       box,
     158                 :             :                        "date",      date,
     159                 :             :                        "id",        id,
     160                 :             :                        "metadata",  metadata,
     161                 :             :                        "read",      read,
     162                 :             :                        "sender",    sender,
     163                 :             :                        "text",      text,
     164                 :             :                        "thread-id", thread_id,
     165                 :             :                        NULL);
     166                 :             : }
     167                 :             : 
     168                 :             : /**
     169                 :             :  * messages_is_thread:
     170                 :             :  * @messages: a `JsonArray`
     171                 :             :  *
     172                 :             :  * Check if @messages is a thread of messages, or a summary of threads.
     173                 :             :  *
     174                 :             :  * Returns: %TRUE if @messages is a conversation thread
     175                 :             :  */
     176                 :             : static gboolean
     177                 :           3 : messages_is_thread (JsonArray *messages)
     178                 :             : {
     179                 :           3 :   JsonObject *message;
     180                 :           3 :   int64_t first, second;
     181                 :             : 
     182                 :             :   /* TODO: A thread with a single message can't be distinguished from
     183                 :             :    *       a summary with a single thread; in fact both could be true.
     184                 :             :    *       If we assume the latter is true exclusively, we will get
     185                 :             :    *       caught in a loop requesting the full thread. */
     186         [ +  + ]:           3 :   if (json_array_get_length (messages) < 2)
     187                 :             :     return TRUE;
     188                 :             : 
     189                 :           2 :   message = json_array_get_object_element (messages, 0);
     190                 :           2 :   first = json_object_get_int_member (message, "thread_id");
     191                 :             : 
     192                 :           2 :   message = json_array_get_object_element (messages, 1);
     193                 :           2 :   second = json_object_get_int_member (message, "thread_id");
     194                 :             : 
     195                 :           2 :   return first == second;
     196                 :             : }
     197                 :             : 
     198                 :             : static void
     199                 :           2 : valent_sms_plugin_handle_thread (ValentSmsPlugin *self,
     200                 :             :                                  JsonArray       *messages)
     201                 :             : {
     202                 :           4 :   g_autoptr (GPtrArray) results = NULL;
     203                 :           2 :   unsigned int n_messages;
     204                 :             : 
     205         [ +  - ]:           2 :   g_assert (VALENT_IS_SMS_PLUGIN (self));
     206         [ -  + ]:           2 :   g_assert (messages != NULL);
     207                 :             : 
     208                 :             :   /* Handle each message */
     209                 :           2 :   n_messages = json_array_get_length (messages);
     210                 :           2 :   results = g_ptr_array_new_with_free_func (g_object_unref);
     211                 :             : 
     212         [ +  + ]:           5 :   for (unsigned int i = 0; i < n_messages; i++)
     213                 :             :     {
     214                 :           3 :       JsonNode *message_node;
     215                 :           3 :       ValentMessage *message;
     216                 :             : 
     217                 :           3 :       message_node = json_array_get_element (messages, i);
     218                 :           3 :       message = valent_sms_plugin_deserialize_message (self, message_node);
     219                 :           3 :       g_ptr_array_add (results, message);
     220                 :             :     }
     221                 :             : 
     222         [ +  - ]:           2 :   valent_sms_store_add_messages (self->store, results, NULL, NULL, NULL);
     223                 :           2 : }
     224                 :             : 
     225                 :             : static void
     226                 :           3 : valent_sms_plugin_handle_messages (ValentSmsPlugin *self,
     227                 :             :                                    JsonNode        *packet)
     228                 :             : {
     229                 :           3 :   JsonObject *body;
     230                 :           3 :   JsonArray *messages;
     231                 :           3 :   unsigned int n_messages;
     232                 :             : 
     233         [ +  - ]:           3 :   g_assert (VALENT_IS_SMS_PLUGIN (self));
     234         [ -  + ]:           3 :   g_assert (VALENT_IS_PACKET (packet));
     235                 :             : 
     236                 :           3 :   body = valent_packet_get_body (packet);
     237                 :           3 :   messages = json_object_get_array_member (body, "messages");
     238                 :           3 :   n_messages = json_array_get_length (messages);
     239                 :             : 
     240                 :             :   /* This would typically mean "all threads have been deleted", but it's more
     241                 :             :    * reasonable to assume this was the result of an error. */
     242         [ +  - ]:           3 :   if (n_messages == 0)
     243                 :             :     return;
     244                 :             : 
     245                 :             :   /* If this is a thread of messages we'll add them to the store */
     246         [ +  + ]:           3 :   if (messages_is_thread (messages))
     247                 :             :     {
     248                 :           2 :       valent_sms_plugin_handle_thread (self, messages);
     249                 :           2 :       return;
     250                 :             :     }
     251                 :             : 
     252                 :             :   /* If this is a summary of threads we'll request each new thread */
     253         [ +  + ]:           3 :   for (unsigned int i = 0; i < n_messages; i++)
     254                 :             :     {
     255                 :           2 :       JsonObject *message;
     256                 :           2 :       int64_t thread_id;
     257                 :           2 :       int64_t thread_date;
     258                 :           2 :       int64_t cache_date;
     259                 :             : 
     260                 :           2 :       message = json_array_get_object_element (messages, i);
     261                 :           2 :       thread_id = json_object_get_int_member (message, "thread_id");
     262                 :           2 :       thread_date = json_object_get_int_member (message, "date");
     263                 :             : 
     264                 :             :       /* Get the last cached date and compare timestamps */
     265                 :           2 :       cache_date = valent_sms_store_get_thread_date (self->store, thread_id);
     266                 :             : 
     267         [ +  - ]:           2 :       if (cache_date < thread_date)
     268                 :           2 :         valent_sms_plugin_request_conversation (self, thread_id, cache_date, 0);
     269                 :             :     }
     270                 :             : }
     271                 :             : 
     272                 :             : static void
     273                 :           2 : valent_sms_plugin_request_conversation (ValentSmsPlugin *self,
     274                 :             :                                         int64_t          thread_id,
     275                 :             :                                         int64_t          start_date,
     276                 :             :                                         int64_t          max_results)
     277                 :             : {
     278                 :           2 :   g_autoptr (JsonBuilder) builder = NULL;
     279   [ -  +  -  - ]:           2 :   g_autoptr (JsonNode) packet = NULL;
     280                 :             : 
     281         [ +  - ]:           2 :   g_return_if_fail (VALENT_IS_SMS_PLUGIN (self));
     282         [ -  + ]:           2 :   g_return_if_fail (thread_id >= 0);
     283                 :             : 
     284                 :           2 :   valent_packet_init (&builder, "kdeconnect.sms.request_conversation");
     285                 :           2 :   json_builder_set_member_name (builder, "threadID");
     286                 :           2 :   json_builder_add_int_value (builder, thread_id);
     287                 :             : 
     288         [ -  + ]:           2 :   if (start_date > 0)
     289                 :             :     {
     290                 :           0 :       json_builder_set_member_name (builder, "rangeStartTimestamp");
     291                 :           0 :       json_builder_add_int_value (builder, start_date);
     292                 :             :     }
     293                 :             : 
     294         [ -  + ]:           2 :   if (max_results > 0)
     295                 :             :     {
     296                 :           0 :       json_builder_set_member_name (builder, "numberToRequest");
     297                 :           0 :       json_builder_add_int_value (builder, max_results);
     298                 :             :     }
     299                 :             : 
     300                 :           2 :   packet = valent_packet_end (&builder);
     301                 :             : 
     302         [ +  - ]:           2 :   valent_device_plugin_queue_packet (VALENT_DEVICE_PLUGIN (self), packet);
     303                 :             : }
     304                 :             : 
     305                 :             : static void
     306                 :           4 : valent_sms_plugin_request_conversations (ValentSmsPlugin *self)
     307                 :             : {
     308                 :           4 :   g_autoptr (JsonBuilder) builder = NULL;
     309   [ -  -  -  + ]:           4 :   g_autoptr (JsonNode) packet = NULL;
     310                 :             : 
     311   [ +  -  -  - ]:           4 :   g_return_if_fail (VALENT_IS_SMS_PLUGIN (self));
     312                 :             : 
     313                 :           4 :   valent_packet_init (&builder, "kdeconnect.sms.request_conversations");
     314                 :           4 :   packet = valent_packet_end (&builder);
     315                 :             : 
     316         [ +  - ]:           4 :   valent_device_plugin_queue_packet (VALENT_DEVICE_PLUGIN (self), packet);
     317                 :             : }
     318                 :             : 
     319                 :             : static void
     320                 :           0 : valent_sms_plugin_request (ValentSmsPlugin *self,
     321                 :             :                            ValentMessage   *message)
     322                 :             : {
     323                 :           0 :   g_autoptr (JsonBuilder) builder = NULL;
     324   [ #  #  #  # ]:           0 :   g_autoptr (JsonNode) packet = NULL;
     325                 :           0 :   GVariant *metadata;
     326   [ #  #  #  # ]:           0 :   g_autoptr (GVariant) addresses = NULL;
     327                 :           0 :   JsonNode *addresses_node = NULL;
     328                 :           0 :   int sub_id = -1;
     329                 :           0 :   const char *text;
     330                 :             : 
     331         [ #  # ]:           0 :   g_return_if_fail (VALENT_IS_SMS_PLUGIN (self));
     332         [ #  # ]:           0 :   g_return_if_fail (VALENT_IS_MESSAGE (message));
     333                 :             : 
     334                 :             :   // Get the data
     335         [ #  # ]:           0 :   if ((metadata = valent_message_get_metadata (message)) == NULL)
     336                 :           0 :     g_return_if_reached ();
     337                 :             : 
     338         [ #  # ]:           0 :   if ((addresses = g_variant_lookup_value (metadata, "addresses", NULL)) == NULL)
     339                 :           0 :     g_return_if_reached ();
     340                 :             : 
     341         [ #  # ]:           0 :   if (!g_variant_lookup (metadata, "sub_id", "i", &sub_id))
     342                 :           0 :       sub_id = -1;
     343                 :             : 
     344                 :             :   // Build the packet
     345                 :           0 :   valent_packet_init (&builder, "kdeconnect.sms.request");
     346                 :             : 
     347                 :           0 :   json_builder_set_member_name (builder, "version");
     348                 :           0 :   json_builder_add_int_value (builder, 2);
     349                 :             : 
     350                 :           0 :   addresses_node = json_gvariant_serialize (addresses);
     351                 :           0 :   json_builder_set_member_name (builder, "addresses");
     352                 :           0 :   json_builder_add_value (builder, addresses_node);
     353                 :             : 
     354                 :           0 :   text = valent_message_get_text (message);
     355                 :           0 :   json_builder_set_member_name (builder, "messageBody");
     356                 :           0 :   json_builder_add_string_value (builder, text);
     357                 :             : 
     358                 :           0 :   json_builder_set_member_name (builder, "subID");
     359                 :           0 :   json_builder_add_int_value (builder, sub_id);
     360                 :             : 
     361                 :           0 :   packet = valent_packet_end (&builder);
     362                 :             : 
     363                 :           0 :   valent_device_plugin_queue_packet (VALENT_DEVICE_PLUGIN (self), packet);
     364                 :             : }
     365                 :             : 
     366                 :             : /*
     367                 :             :  * GActions
     368                 :             :  */
     369                 :             : static void
     370                 :           1 : fetch_action (GSimpleAction *action,
     371                 :             :               GVariant      *parameter,
     372                 :             :               gpointer       user_data)
     373                 :             : {
     374                 :           1 :   ValentSmsPlugin *self = VALENT_SMS_PLUGIN (user_data);
     375                 :             : 
     376         [ +  - ]:           1 :   g_assert (VALENT_IS_SMS_PLUGIN (self));
     377                 :             : 
     378                 :           1 :   valent_sms_plugin_request_conversations (self);
     379                 :           1 : }
     380                 :             : 
     381                 :             : static gboolean
     382                 :           0 : on_send_message (ValentSmsWindow *window,
     383                 :             :                  ValentMessage   *message,
     384                 :             :                  ValentSmsPlugin *self)
     385                 :             : {
     386         [ #  # ]:           0 :   g_assert (VALENT_IS_SMS_WINDOW (window));
     387         [ #  # ]:           0 :   g_assert (VALENT_IS_MESSAGE (message));
     388                 :             : 
     389                 :           0 :   valent_sms_plugin_request (self, message);
     390                 :             : 
     391                 :           0 :   return TRUE;
     392                 :             : }
     393                 :             : 
     394                 :             : static void
     395                 :           1 : messaging_action (GSimpleAction *action,
     396                 :             :                   GVariant      *parameter,
     397                 :             :                   gpointer       user_data)
     398                 :             : {
     399                 :           1 :   ValentSmsPlugin *self = VALENT_SMS_PLUGIN (user_data);
     400                 :           1 :   ValentDevice *device;
     401                 :             : 
     402         [ +  - ]:           1 :   g_assert (VALENT_IS_SMS_PLUGIN (self));
     403                 :             : 
     404         [ -  + ]:           1 :   if (!gtk_is_initialized ())
     405                 :             :     {
     406                 :           0 :       g_warning ("%s: No display available", G_STRFUNC);
     407                 :           0 :       return;
     408                 :             :     }
     409                 :             : 
     410         [ +  - ]:           1 :   if (self->window == NULL)
     411                 :             :     {
     412                 :           1 :       ValentContactStore *store;
     413                 :             : 
     414                 :           1 :       device = valent_extension_get_object (VALENT_EXTENSION (self));
     415                 :           1 :       store = valent_contacts_ensure_store (valent_contacts_get_default (),
     416                 :             :                                             valent_device_get_id (device),
     417                 :             :                                             valent_device_get_name (device));
     418                 :             : 
     419                 :           1 :       self->window = g_object_new (VALENT_TYPE_SMS_WINDOW,
     420                 :             :                                    "contact-store", store,
     421                 :             :                                    "message-store", self->store,
     422                 :             :                                    NULL);
     423                 :           1 :       g_object_add_weak_pointer (G_OBJECT (self->window),
     424                 :           1 :                                  (gpointer) &self->window);
     425                 :             : 
     426                 :           1 :       g_signal_connect_object (self->window,
     427                 :             :                                "send-message",
     428                 :             :                                G_CALLBACK (on_send_message),
     429                 :             :                                self, 0);
     430                 :             :     }
     431                 :             : 
     432                 :           1 :   gtk_window_present_with_time (GTK_WINDOW (self->window), GDK_CURRENT_TIME);
     433                 :             : }
     434                 :             : 
     435                 :             : static const GActionEntry actions[] = {
     436                 :             :     {"fetch",     fetch_action,     NULL, NULL, NULL},
     437                 :             :     {"messaging", messaging_action, NULL, NULL, NULL}
     438                 :             : };
     439                 :             : 
     440                 :             : /*
     441                 :             :  * ValentDevicePlugin
     442                 :             :  */
     443                 :             : static void
     444                 :          10 : valent_sms_plugin_update_state (ValentDevicePlugin *plugin,
     445                 :             :                                 ValentDeviceState   state)
     446                 :             : {
     447                 :          10 :   ValentSmsPlugin *self = VALENT_SMS_PLUGIN (plugin);
     448                 :          10 :   gboolean available;
     449                 :             : 
     450         [ +  - ]:          10 :   g_assert (VALENT_IS_SMS_PLUGIN (self));
     451                 :             : 
     452                 :          10 :   available = (state & VALENT_DEVICE_STATE_CONNECTED) != 0 &&
     453                 :             :               (state & VALENT_DEVICE_STATE_PAIRED) != 0;
     454                 :             : 
     455                 :          10 :   valent_extension_toggle_actions (VALENT_EXTENSION (plugin), available);
     456                 :             : 
     457                 :             :   /* Request summary of messages */
     458         [ +  + ]:          10 :   if (available)
     459                 :           3 :     valent_sms_plugin_request_conversations (self);
     460                 :          10 : }
     461                 :             : 
     462                 :             : static void
     463                 :           3 : valent_sms_plugin_handle_packet (ValentDevicePlugin *plugin,
     464                 :             :                                  const char         *type,
     465                 :             :                                  JsonNode           *packet)
     466                 :             : {
     467                 :           3 :   ValentSmsPlugin *self = VALENT_SMS_PLUGIN (plugin);
     468                 :             : 
     469         [ +  - ]:           3 :   g_assert (VALENT_IS_SMS_PLUGIN (plugin));
     470         [ -  + ]:           3 :   g_assert (type != NULL);
     471         [ -  + ]:           3 :   g_assert (VALENT_IS_PACKET (packet));
     472                 :             : 
     473         [ +  - ]:           3 :   if (g_str_equal (type, "kdeconnect.sms.messages"))
     474                 :           3 :     valent_sms_plugin_handle_messages (self, packet);
     475                 :             :   else
     476                 :           3 :     g_assert_not_reached ();
     477                 :           3 : }
     478                 :             : 
     479                 :             : /*
     480                 :             :  * ValentObject
     481                 :             :  */
     482                 :             : static void
     483                 :           6 : valent_sms_plugin_destroy (ValentObject *object)
     484                 :             : {
     485                 :           6 :   ValentSmsPlugin *self = VALENT_SMS_PLUGIN (object);
     486                 :           6 :   ValentDevicePlugin *plugin = VALENT_DEVICE_PLUGIN (object);
     487                 :             : 
     488                 :             :   /* Close message window and drop SMS Store */
     489         [ +  + ]:           6 :   g_clear_pointer (&self->window, gtk_window_destroy);
     490         [ +  + ]:           6 :   g_clear_object (&self->store);
     491                 :             : 
     492                 :           6 :   valent_device_plugin_set_menu_item (plugin, "device.sms.messaging", NULL);
     493                 :             : 
     494                 :           6 :   VALENT_OBJECT_CLASS (valent_sms_plugin_parent_class)->destroy (object);
     495                 :           6 : }
     496                 :             : 
     497                 :             : /*
     498                 :             :  * GObject
     499                 :             :  */
     500                 :             : static void
     501                 :           3 : valent_sms_plugin_constructed (GObject *object)
     502                 :             : {
     503                 :           3 :   ValentSmsPlugin *self = VALENT_SMS_PLUGIN (object);
     504                 :           3 :   ValentDevicePlugin *plugin = VALENT_DEVICE_PLUGIN (object);
     505                 :           3 :   ValentDevice *device;
     506                 :           3 :   ValentContext *context = NULL;
     507                 :             : 
     508                 :             :   /* Load SMS Store */
     509                 :           3 :   device = valent_extension_get_object (VALENT_EXTENSION (self));
     510                 :           3 :   context = valent_device_get_context (device);
     511                 :           3 :   self->store = g_object_new (VALENT_TYPE_SMS_STORE,
     512                 :             :                               "domain", "plugin",
     513                 :             :                               "id",     "sms",
     514                 :             :                               "parent", context,
     515                 :             :                               NULL);
     516                 :             : 
     517                 :           3 :   g_action_map_add_action_entries (G_ACTION_MAP (plugin),
     518                 :             :                                    actions,
     519                 :             :                                    G_N_ELEMENTS (actions),
     520                 :             :                                    plugin);
     521                 :           3 :   valent_device_plugin_set_menu_action (plugin,
     522                 :             :                                         "device.sms.messaging",
     523                 :           3 :                                         _("Messaging"),
     524                 :             :                                         "sms-symbolic");
     525                 :             : 
     526                 :           3 :   G_OBJECT_CLASS (valent_sms_plugin_parent_class)->constructed (object);
     527                 :           3 : }
     528                 :             : 
     529                 :             : static void
     530                 :           3 : valent_sms_plugin_finalize (GObject *object)
     531                 :             : {
     532                 :           3 :   ValentSmsPlugin *self = VALENT_SMS_PLUGIN (object);
     533                 :             : 
     534         [ -  + ]:           3 :   if (self->window)
     535                 :           0 :     g_clear_pointer (&self->window, gtk_window_destroy);
     536         [ -  + ]:           3 :   g_clear_object (&self->store);
     537                 :             : 
     538                 :           3 :   G_OBJECT_CLASS (valent_sms_plugin_parent_class)->finalize (object);
     539                 :           3 : }
     540                 :             : 
     541                 :             : static void
     542                 :           4 : valent_sms_plugin_class_init (ValentSmsPluginClass *klass)
     543                 :             : {
     544                 :           4 :   GObjectClass *object_class = G_OBJECT_CLASS (klass);
     545                 :           4 :   ValentObjectClass *vobject_class = VALENT_OBJECT_CLASS (klass);
     546                 :           4 :   ValentDevicePluginClass *plugin_class = VALENT_DEVICE_PLUGIN_CLASS (klass);
     547                 :             : 
     548                 :           4 :   object_class->finalize = valent_sms_plugin_finalize;
     549                 :             : 
     550                 :           4 :   object_class->constructed = valent_sms_plugin_constructed;
     551                 :           4 :   plugin_class->handle_packet = valent_sms_plugin_handle_packet;
     552                 :           4 :   plugin_class->update_state = valent_sms_plugin_update_state;
     553                 :             : 
     554                 :           4 :   vobject_class->destroy = valent_sms_plugin_destroy;
     555                 :             : }
     556                 :             : 
     557                 :             : static void
     558                 :           3 : valent_sms_plugin_init (ValentSmsPlugin *self)
     559                 :             : {
     560                 :           3 : }
     561                 :             : 
        

Generated by: LCOV version 2.0-1