LCOV - code coverage report
Current view: top level - src/plugins/contacts - valent-contacts-plugin.c (source / functions) Coverage Total Hit
Test: Code Coverage Lines: 93.7 % 221 207
Test Date: 2024-04-13 23:00:06 Functions: 100.0 % 17 17
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 57.9 % 140 81

             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-contacts-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-contacts-plugin.h"
      13                 :             : 
      14                 :             : 
      15                 :             : struct _ValentContactsPlugin
      16                 :             : {
      17                 :             :   ValentDevicePlugin  parent_instance;
      18                 :             : 
      19                 :             :   GCancellable       *cancellable;
      20                 :             : 
      21                 :             :   ValentContactStore *local_store;
      22                 :             :   ValentContactStore *remote_store;
      23                 :             : };
      24                 :             : 
      25   [ +  +  +  - ]:          29 : G_DEFINE_FINAL_TYPE (ValentContactsPlugin, valent_contacts_plugin, VALENT_TYPE_DEVICE_PLUGIN)
      26                 :             : 
      27                 :             : 
      28                 :             : /*
      29                 :             :  * Local Contacts
      30                 :             :  */
      31                 :             : static void
      32                 :           1 : valent_contact_store_query_vcards_cb (ValentContactStore   *store,
      33                 :             :                                       GAsyncResult         *result,
      34                 :             :                                       ValentContactsPlugin *self)
      35                 :             : {
      36                 :           1 :   g_autoptr (JsonBuilder) builder = NULL;
      37   [ -  -  -  + ]:           1 :   g_autoptr (JsonNode) response = NULL;
      38   [ -  -  +  - ]:           1 :   g_autoslist (GObject) contacts = NULL;
      39                 :           1 :   g_autoptr (GError) error = NULL;
      40                 :             : 
      41         [ +  - ]:           1 :   g_assert (VALENT_IS_CONTACT_STORE (store));
      42                 :             : 
      43                 :           1 :   contacts = valent_contact_store_query_finish (store, result, &error);
      44                 :             : 
      45         [ -  + ]:           1 :   if (error != NULL)
      46                 :             :     {
      47                 :           0 :       g_warning ("%s(): %s", G_STRFUNC, error->message);
      48         [ #  # ]:           0 :       return;
      49                 :             :     }
      50                 :             : 
      51                 :           1 :   valent_packet_init (&builder, "kdeconnect.contacts.response_vcards");
      52                 :             : 
      53                 :             :   /* Add UIDs */
      54                 :           1 :   json_builder_set_member_name (builder, "uids");
      55                 :           1 :   json_builder_begin_array (builder);
      56                 :             : 
      57         [ +  + ]:           3 :   for (const GSList *iter = contacts; iter; iter = iter->next)
      58                 :             :     {
      59                 :           2 :       const char *uid;
      60                 :             : 
      61                 :           2 :       uid = e_contact_get_const (iter->data, E_CONTACT_UID);
      62                 :           2 :       json_builder_add_string_value (builder, uid);
      63                 :             :     }
      64                 :           1 :   json_builder_end_array (builder);
      65                 :             : 
      66                 :             :   /* Add vCard data */
      67         [ +  + ]:           3 :   for (const GSList *iter = contacts; iter; iter = iter->next)
      68                 :             :     {
      69                 :           2 :       const char *uid;
      70                 :           2 :       g_autofree char *vcard_data = NULL;
      71                 :             : 
      72                 :           2 :       uid = e_contact_get_const (iter->data, E_CONTACT_UID);
      73                 :           2 :       json_builder_set_member_name (builder, uid);
      74                 :             : 
      75                 :           2 :       vcard_data = e_vcard_to_string (iter->data, EVC_FORMAT_VCARD_21);
      76                 :           2 :       json_builder_add_string_value (builder, vcard_data);
      77                 :             :     }
      78                 :             : 
      79                 :             :   /* Finish and send the response */
      80                 :           1 :   response = valent_packet_end (&builder);
      81         [ -  + ]:           1 :   valent_device_plugin_queue_packet (VALENT_DEVICE_PLUGIN (self), response);
      82                 :             : }
      83                 :             : 
      84                 :             : static void
      85                 :           1 : valent_contact_plugin_handle_request_vcards_by_uid (ValentContactsPlugin *self,
      86                 :             :                                                     JsonNode             *packet)
      87                 :             : {
      88                 :           1 :   GSettings *settings;
      89                 :           1 :   g_autofree EBookQuery **queries = NULL;
      90                 :           1 :   g_autoptr (EBookQuery) query = NULL;
      91         [ +  - ]:           1 :   g_autofree char *sexp = NULL;
      92                 :           1 :   JsonArray *uids;
      93                 :           1 :   unsigned int n_uids, n_queries;
      94                 :             : 
      95         [ +  - ]:           1 :   g_assert (VALENT_IS_CONTACTS_PLUGIN (self));
      96                 :             : 
      97                 :             : #ifndef __clang_analyzer__
      98                 :             :   /* Bail if exporting is disabled */
      99                 :           1 :   settings = valent_extension_get_settings (VALENT_EXTENSION (self));
     100                 :             : 
     101   [ +  -  -  + ]:           1 :   if (self->local_store == NULL || !g_settings_get_boolean (settings, "local-sync"))
     102                 :           0 :     return;
     103                 :             : 
     104         [ -  + ]:           1 :   if (!valent_packet_get_array (packet, "uids", &uids))
     105                 :             :     {
     106                 :           0 :       g_debug ("%s(): expected \"uids\" field holding an array",
     107                 :             :                G_STRFUNC);
     108                 :           0 :       return;
     109                 :             :     }
     110                 :             : 
     111                 :             :   /* Build a list of queries */
     112                 :           1 :   n_uids = json_array_get_length (uids);
     113         [ -  + ]:           1 :   queries = g_new (EBookQuery *, n_uids);
     114                 :           1 :   n_queries = 0;
     115                 :             : 
     116         [ +  + ]:           3 :   for (unsigned int i = 0; i < n_uids; i++)
     117                 :             :     {
     118                 :           2 :       JsonNode *element = json_array_get_element (uids, i);
     119                 :           2 :       const char *uid = NULL;
     120                 :             : 
     121         [ +  - ]:           2 :       if G_LIKELY (json_node_get_value_type (element) == G_TYPE_STRING)
     122                 :           2 :         uid = json_node_get_string (element);
     123                 :             : 
     124   [ +  -  +  - ]:           2 :       if G_UNLIKELY (uid == NULL || *uid == '\0')
     125                 :             :         {
     126                 :           0 :           g_debug ("%s(): expected \"uids\" element to contain a string",
     127                 :             :                    G_STRFUNC);
     128                 :           0 :           continue;
     129                 :             :         }
     130                 :             : 
     131                 :           2 :       queries[n_queries++] = e_book_query_field_test (E_CONTACT_UID,
     132                 :             :                                                       E_BOOK_QUERY_IS,
     133                 :             :                                                       uid);
     134                 :             :     }
     135                 :             : 
     136         [ +  - ]:           1 :   if (n_queries == 0)
     137                 :             :     return;
     138                 :             : 
     139                 :           1 :   query = e_book_query_or (n_queries, queries, TRUE);
     140                 :           1 :   sexp = e_book_query_to_string (query);
     141                 :             : 
     142                 :           1 :   valent_contact_store_query (self->local_store,
     143                 :             :                               sexp,
     144                 :             :                               self->cancellable,
     145                 :             :                               (GAsyncReadyCallback)valent_contact_store_query_vcards_cb,
     146                 :             :                               self);
     147                 :             : #endif /* __clang_analyzer__ */
     148                 :             : }
     149                 :             : 
     150                 :             : static void
     151                 :           1 : valent_contact_store_query_uids_cb (ValentContactStore   *store,
     152                 :             :                                     GAsyncResult         *result,
     153                 :             :                                     ValentContactsPlugin *self)
     154                 :             : {
     155                 :           1 :   g_autoptr (JsonBuilder) builder = NULL;
     156   [ -  -  -  + ]:           1 :   g_autoptr (JsonNode) response = NULL;
     157   [ -  -  +  - ]:           1 :   g_autoslist (GObject) contacts = NULL;
     158                 :           1 :   g_autoptr (GError) error = NULL;
     159                 :             : 
     160         [ +  - ]:           1 :   g_assert (VALENT_IS_CONTACT_STORE (store));
     161                 :             : 
     162                 :           1 :   contacts = valent_contact_store_query_finish (store, result, &error);
     163                 :             : 
     164                 :             :   /* If the operation was cancelled, we're about to dispose. For any other
     165                 :             :    * error log a warning and send an empty list. */
     166         [ -  + ]:           1 :   if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
     167         [ #  # ]:           0 :     return;
     168                 :             : 
     169         [ -  + ]:           1 :   if (error != NULL)
     170                 :           0 :     g_warning ("%s(): %s", G_STRFUNC, error->message);
     171                 :             : 
     172                 :             :   /* Build response */
     173                 :           1 :   valent_packet_init (&builder, "kdeconnect.contacts.response_uids_timestamps");
     174                 :             : 
     175         [ +  + ]:           3 :   for (const GSList *iter = contacts; iter; iter = iter->next)
     176                 :             :     {
     177                 :           2 :       const char *uid;
     178                 :           2 :       int64_t timestamp = 0;
     179                 :             : 
     180                 :           2 :       uid = e_contact_get_const (iter->data, E_CONTACT_UID);
     181                 :           2 :       json_builder_set_member_name (builder, uid);
     182                 :             : 
     183                 :             :       // TODO: We probably need to convert between the custom field
     184                 :             :       // `X-KDECONNECT-TIMESTAMP` and `E_CONTACT_REV` to set a proper timestamp
     185                 :           2 :       timestamp = 0;
     186                 :           2 :       json_builder_add_int_value (builder, timestamp);
     187                 :             :     }
     188                 :             : 
     189                 :           1 :   response = valent_packet_end (&builder);
     190         [ -  + ]:           1 :   valent_device_plugin_queue_packet (VALENT_DEVICE_PLUGIN (self), response);
     191                 :             : }
     192                 :             : 
     193                 :             : static void
     194                 :           1 : valent_contact_plugin_handle_request_all_uids_timestamps (ValentContactsPlugin *self,
     195                 :             :                                                           JsonNode             *packet)
     196                 :             : {
     197                 :           1 :   GSettings *settings;
     198                 :           0 :   g_autoptr (EBookQuery) query = NULL;
     199         [ +  - ]:           1 :   g_autofree char *sexp = NULL;
     200                 :             : 
     201         [ +  - ]:           1 :   g_assert (VALENT_IS_CONTACTS_PLUGIN (self));
     202                 :             : 
     203                 :             :   /* Bail if exporting is disabled */
     204                 :           1 :   settings = valent_extension_get_settings (VALENT_EXTENSION (self));
     205                 :             : 
     206   [ +  -  -  + ]:           1 :   if (self->local_store == NULL || !g_settings_get_boolean (settings, "local-sync"))
     207                 :           0 :     return;
     208                 :             : 
     209                 :           1 :   query = e_book_query_vcard_field_exists (EVC_UID);
     210                 :           1 :   sexp = e_book_query_to_string (query);
     211                 :             : 
     212                 :           1 :   valent_contact_store_query (self->local_store,
     213                 :             :                               sexp,
     214                 :             :                               self->cancellable,
     215                 :             :                               (GAsyncReadyCallback)valent_contact_store_query_uids_cb,
     216                 :             :                               self);
     217                 :             : }
     218                 :             : 
     219                 :             : /*
     220                 :             :  * Remote Contacts
     221                 :             :  */
     222                 :             : static void
     223                 :           1 : valent_contact_plugin_handle_response_uids_timestamps (ValentContactsPlugin *self,
     224                 :             :                                                        JsonNode             *packet)
     225                 :             : {
     226                 :           2 :   g_autoptr (JsonNode) request = NULL;
     227         [ +  - ]:           1 :   g_autoptr (JsonBuilder) builder = NULL;
     228                 :           1 :   JsonObjectIter iter;
     229                 :           1 :   const char *uid;
     230                 :           1 :   JsonNode *node;
     231                 :           1 :   unsigned int n_requested = 0;
     232                 :             : 
     233         [ +  - ]:           1 :   g_assert (VALENT_IS_CONTACTS_PLUGIN (self));
     234                 :             : 
     235                 :             :   /* Start the packet */
     236                 :           1 :   valent_packet_init (&builder, "kdeconnect.contacts.request_vcards_by_uid");
     237                 :           1 :   json_builder_set_member_name (builder, "uids");
     238                 :           1 :   json_builder_begin_array (builder);
     239                 :             : 
     240                 :           1 :   json_object_iter_init (&iter, valent_packet_get_body (packet));
     241                 :             : 
     242         [ +  + ]:           4 :   while (json_object_iter_next (&iter, &uid, &node))
     243                 :             :     {
     244                 :           3 :       int64_t timestamp = 0;
     245                 :             : 
     246                 :             :       // skip the "uids" array
     247         [ +  + ]:           3 :       if G_UNLIKELY (g_str_equal ("uids", uid))
     248                 :           1 :         continue;
     249                 :             : 
     250         [ +  - ]:           2 :       if G_LIKELY (json_node_get_value_type (node) == G_TYPE_INT64)
     251                 :           2 :         timestamp = json_node_get_int (node);
     252                 :             : 
     253                 :             :       /* Check if the contact is new or updated */
     254         [ -  + ]:           2 :       if (0 != timestamp)
     255                 :             :       //if (valent_contact_store_get_timestamp (self->store, uid) != timestamp)
     256                 :             :         {
     257                 :           2 :           n_requested++;
     258                 :           2 :           json_builder_add_string_value (builder, uid);
     259                 :             :         }
     260                 :             :     }
     261                 :             : 
     262                 :           1 :   json_builder_end_array (builder);
     263                 :           1 :   request = valent_packet_end (&builder);
     264                 :             : 
     265         [ +  - ]:           1 :   if (n_requested > 0)
     266                 :           1 :     valent_device_plugin_queue_packet (VALENT_DEVICE_PLUGIN (self), request);
     267                 :           1 : }
     268                 :             : 
     269                 :             : static void
     270                 :           1 : valent_contact_store_add_contacts_cb (ValentContactStore *store,
     271                 :             :                                       GAsyncResult       *result,
     272                 :             :                                       gpointer            user_data)
     273                 :             : {
     274                 :           2 :   g_autoptr (GError) error = NULL;
     275                 :             : 
     276   [ -  +  -  - ]:           1 :   if (!valent_contact_store_add_contacts_finish (store, result, &error) &&
     277                 :           0 :       !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
     278                 :           0 :     g_warning ("%s(): %s", G_STRFUNC, error->message);
     279                 :           1 : }
     280                 :             : 
     281                 :             : static void
     282                 :           1 : valent_contact_plugin_handle_response_vcards (ValentContactsPlugin *self,
     283                 :             :                                               JsonNode             *packet)
     284                 :             : {
     285                 :           2 :   g_autoslist (EContact) contacts = NULL;
     286                 :           1 :   JsonObject *body;
     287                 :           1 :   JsonObjectIter iter;
     288                 :           1 :   const char *uid;
     289                 :           1 :   JsonNode *node;
     290                 :             : 
     291         [ +  - ]:           1 :   g_assert (VALENT_IS_CONTACTS_PLUGIN (self));
     292                 :             : 
     293                 :           1 :   body = valent_packet_get_body (packet);
     294                 :           1 :   json_object_iter_init (&iter, body);
     295                 :             : 
     296         [ +  + ]:           4 :   while (json_object_iter_next (&iter, &uid, &node))
     297                 :             :     {
     298                 :           3 :       EContact *contact;
     299                 :           3 :       const char *vcard;
     300                 :             : 
     301                 :             :       /* NOTE: This has the side-effect of ignoring `uids` array, which is fine
     302                 :             :        *       because the contact members are the ultimate source of truth. */
     303         [ +  + ]:           3 :       if G_UNLIKELY (json_node_get_value_type (node) != G_TYPE_STRING)
     304                 :           1 :         continue;
     305                 :             : 
     306                 :           2 :       vcard = json_node_get_string (node);
     307                 :           2 :       contact = e_contact_new_from_vcard_with_uid (vcard, uid);
     308                 :             : 
     309                 :           2 :       contacts = g_slist_append (contacts, contact);
     310                 :             :     }
     311                 :             : 
     312         [ +  - ]:           1 :   if (contacts != NULL)
     313                 :             :     {
     314                 :           1 :       valent_contact_store_add_contacts (self->remote_store,
     315                 :             :                                          contacts,
     316                 :             :                                          self->cancellable,
     317                 :             :                                          (GAsyncReadyCallback)valent_contact_store_add_contacts_cb,
     318                 :             :                                          NULL);
     319                 :             :     }
     320                 :           1 : }
     321                 :             : 
     322                 :             : static void
     323                 :           4 : valent_contacts_plugin_request_all_uids_timestamps (ValentContactsPlugin *self)
     324                 :             : {
     325                 :           8 :   g_autoptr (JsonNode) packet = NULL;
     326                 :             : 
     327         [ +  - ]:           4 :   g_assert (VALENT_IS_CONTACTS_PLUGIN (self));
     328                 :             : 
     329                 :           4 :   packet = valent_packet_new ("kdeconnect.contacts.request_all_uids_timestamps");
     330         [ +  - ]:           4 :   valent_device_plugin_queue_packet (VALENT_DEVICE_PLUGIN (self), packet);
     331                 :           4 : }
     332                 :             : 
     333                 :             : /*
     334                 :             :  * GActions
     335                 :             :  */
     336                 :             : static void
     337                 :           1 : contacts_fetch_action (GSimpleAction *action,
     338                 :             :                        GVariant      *parameter,
     339                 :             :                        gpointer       user_data)
     340                 :             : {
     341                 :           1 :   ValentContactsPlugin *self = VALENT_CONTACTS_PLUGIN (user_data);
     342                 :             : 
     343         [ +  - ]:           1 :   g_assert (VALENT_IS_CONTACTS_PLUGIN (self));
     344                 :             : 
     345                 :           1 :   valent_contacts_plugin_request_all_uids_timestamps (self);
     346                 :           1 : }
     347                 :             : 
     348                 :             : static const GActionEntry actions[] = {
     349                 :             :     {"fetch", contacts_fetch_action, NULL, NULL, NULL}
     350                 :             : };
     351                 :             : 
     352                 :             : /*
     353                 :             :  * ValentDevicePlugin
     354                 :             :  */
     355                 :             : static void
     356                 :          10 : valent_contacts_plugin_update_state (ValentDevicePlugin *plugin,
     357                 :             :                                      ValentDeviceState   state)
     358                 :             : {
     359                 :          10 :   ValentContactsPlugin *self = VALENT_CONTACTS_PLUGIN (plugin);
     360                 :          10 :   gboolean available;
     361                 :             : 
     362         [ +  - ]:          10 :   g_assert (VALENT_IS_CONTACTS_PLUGIN (self));
     363                 :             : 
     364                 :          10 :   available = (state & VALENT_DEVICE_STATE_CONNECTED) != 0 &&
     365                 :             :               (state & VALENT_DEVICE_STATE_PAIRED) != 0;
     366                 :             : 
     367                 :          10 :   valent_extension_toggle_actions (VALENT_EXTENSION (plugin), available);
     368                 :             : 
     369         [ +  + ]:          10 :   if (available)
     370                 :           3 :     valent_contacts_plugin_request_all_uids_timestamps (self);
     371                 :          10 : }
     372                 :             : 
     373                 :             : static void
     374                 :           4 : valent_contacts_plugin_handle_packet (ValentDevicePlugin *plugin,
     375                 :             :                                       const char         *type,
     376                 :             :                                       JsonNode           *packet)
     377                 :             : {
     378                 :           4 :   ValentContactsPlugin *self = VALENT_CONTACTS_PLUGIN (plugin);
     379                 :             : 
     380         [ +  - ]:           4 :   g_assert (VALENT_IS_CONTACTS_PLUGIN (plugin));
     381         [ -  + ]:           4 :   g_assert (type != NULL);
     382         [ -  + ]:           4 :   g_assert (VALENT_IS_PACKET (packet));
     383                 :             : 
     384                 :             :   /* A response to a request for a listing of contacts */
     385         [ +  + ]:           4 :   if (g_str_equal (type, "kdeconnect.contacts.response_uids_timestamps"))
     386                 :           1 :     valent_contact_plugin_handle_response_uids_timestamps (self, packet);
     387                 :             : 
     388                 :             :   /* A response to a request for contacts */
     389         [ +  + ]:           3 :   else if (g_str_equal (type, "kdeconnect.contacts.response_vcards"))
     390                 :           1 :     valent_contact_plugin_handle_response_vcards (self, packet);
     391                 :             : 
     392                 :             :   /* A request for a listing of contacts */
     393         [ +  + ]:           2 :   else if (g_str_equal (type, "kdeconnect.contacts.request_all_uids_timestamps"))
     394                 :           1 :     valent_contact_plugin_handle_request_all_uids_timestamps (self, packet);
     395                 :             : 
     396                 :             :   /* A request for contacts */
     397         [ +  - ]:           1 :   else if (g_str_equal (type, "kdeconnect.contacts.request_vcards_by_uid"))
     398                 :           1 :     valent_contact_plugin_handle_request_vcards_by_uid (self, packet);
     399                 :             : 
     400                 :             :   else
     401                 :           0 :     g_assert_not_reached ();
     402                 :           4 : }
     403                 :             : 
     404                 :             : /*
     405                 :             :  * ValentObject
     406                 :             :  */
     407                 :             : static void
     408                 :           6 : valent_contacts_plugin_destroy (ValentObject *object)
     409                 :             : {
     410                 :           6 :   ValentContactsPlugin *self = VALENT_CONTACTS_PLUGIN (object);
     411                 :             : 
     412                 :             :   /* Cancel any pending operations and drop the address books */
     413                 :           6 :   g_cancellable_cancel (self->cancellable);
     414         [ +  + ]:           6 :   g_clear_object (&self->cancellable);
     415         [ +  + ]:           6 :   g_clear_object (&self->remote_store);
     416         [ +  + ]:           6 :   g_clear_object (&self->local_store);
     417                 :             : 
     418                 :           6 :   VALENT_OBJECT_CLASS (valent_contacts_plugin_parent_class)->destroy (object);
     419                 :           6 : }
     420                 :             : 
     421                 :             : /*
     422                 :             :  * GObject
     423                 :             :  */
     424                 :             : static void
     425                 :           3 : valent_contacts_plugin_constructed (GObject *object)
     426                 :             : {
     427                 :           3 :   ValentContactsPlugin *self = VALENT_CONTACTS_PLUGIN (object);
     428                 :           3 :   ValentDevicePlugin *plugin = VALENT_DEVICE_PLUGIN (object);
     429                 :           3 :   ValentContacts *contacts = valent_contacts_get_default ();
     430                 :           3 :   ValentContactStore *store = NULL;
     431                 :           6 :   g_autofree char *local_uid = NULL;
     432                 :           3 :   ValentDevice *device;
     433                 :           3 :   GSettings *settings;
     434                 :             : 
     435                 :           3 :   g_action_map_add_action_entries (G_ACTION_MAP (plugin),
     436                 :             :                                    actions,
     437                 :             :                                    G_N_ELEMENTS (actions),
     438                 :             :                                    plugin);
     439                 :             : 
     440                 :             :   /* Prepare Addressbooks */
     441                 :           3 :   self->cancellable = g_cancellable_new ();
     442                 :           3 :   device = valent_extension_get_object (VALENT_EXTENSION (plugin));
     443                 :           3 :   settings = valent_extension_get_settings (VALENT_EXTENSION (self));
     444                 :             : 
     445                 :           3 :   store = valent_contacts_ensure_store (valent_contacts_get_default (),
     446                 :             :                                         valent_device_get_id (device),
     447                 :             :                                         valent_device_get_name (device));
     448                 :           3 :   g_set_object (&self->remote_store, store);
     449                 :             : 
     450                 :             :   /* Local address book, shared with remote device */
     451                 :           3 :   local_uid = g_settings_get_string (settings, "local-uid");
     452                 :             : 
     453         [ +  + ]:           3 :   if (*local_uid != '\0')
     454                 :             :     {
     455                 :           2 :       unsigned int n_stores = g_list_model_get_n_items (G_LIST_MODEL (contacts));
     456                 :             : 
     457         [ +  - ]:           4 :       for (unsigned int i = 0; i < n_stores; i++)
     458                 :             :         {
     459                 :           2 :           g_autoptr (ValentContactStore) local = NULL;
     460                 :             : 
     461                 :           4 :           local = g_list_model_get_item (G_LIST_MODEL (contacts), i);
     462                 :             : 
     463         [ +  + ]:           4 :           if (g_strcmp0 (valent_contact_store_get_uid (local), local_uid) != 0)
     464         [ +  - ]:           2 :             continue;
     465                 :             : 
     466                 :           2 :           g_set_object (&self->local_store, local);
     467         [ +  - ]:           2 :           break;
     468                 :             :         }
     469                 :             :     }
     470                 :             : 
     471                 :           3 :   G_OBJECT_CLASS (valent_contacts_plugin_parent_class)->constructed (object);
     472                 :           3 : }
     473                 :             : 
     474                 :             : static void
     475                 :           2 : valent_contacts_plugin_class_init (ValentContactsPluginClass *klass)
     476                 :             : {
     477                 :           2 :   GObjectClass *object_class = G_OBJECT_CLASS (klass);
     478                 :           2 :   ValentObjectClass *vobject_class = VALENT_OBJECT_CLASS (klass);
     479                 :           2 :   ValentDevicePluginClass *plugin_class = VALENT_DEVICE_PLUGIN_CLASS (klass);
     480                 :             : 
     481                 :           2 :   object_class->constructed = valent_contacts_plugin_constructed;
     482                 :             : 
     483                 :           2 :   vobject_class->destroy = valent_contacts_plugin_destroy;
     484                 :             : 
     485                 :           2 :   plugin_class->handle_packet = valent_contacts_plugin_handle_packet;
     486                 :           2 :   plugin_class->update_state = valent_contacts_plugin_update_state;
     487                 :             : }
     488                 :             : 
     489                 :             : static void
     490                 :           3 : valent_contacts_plugin_init (ValentContactsPlugin *self)
     491                 :             : {
     492                 :           3 : }
     493                 :             : 
        

Generated by: LCOV version 2.0-1