]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-utils.c
Merge remote-tracking branch 'jonny/ft'
[empathy.git] / libempathy / empathy-utils.c
index 24fdf97f354113c6ebf216d31a7ae26fa1b32156..972abe65e2ae6011aef33d1f5a6a0a6b4851145a 100644 (file)
@@ -80,6 +80,16 @@ static struct {
   { NULL, },
 };
 
+static gboolean
+properties_contains (gchar **list,
+                    gint length,
+                    const gchar *property);
+
+static gboolean
+check_writeable_property (TpConnection *connection,
+                         FolksIndividual *individual,
+                         gchar *property);
+
 void
 empathy_init (void)
 {
@@ -358,6 +368,8 @@ create_errors_to_message_hash (void)
     _("The length of the server certificate, or the depth of the "
     "server certificate chain, exceed the limits imposed by the "
     "cryptography library"));
+  g_hash_table_insert (errors, TP_ERROR_STR_SOFTWARE_UPGRADE_REQUIRED,
+    _("Your software is too old"));
 
   return errors;
 }
@@ -802,10 +814,10 @@ empathy_connection_can_add_personas (TpConnection *connection)
 }
 
 gboolean
-empathy_connection_can_alias_personas (TpConnection *connection)
+empathy_connection_can_alias_personas (TpConnection *connection,
+                                      FolksIndividual *individual)
 {
   gboolean retval;
-  FolksPersonaStore *persona_store;
 
   g_return_val_if_fail (TP_IS_CONNECTION (connection), FALSE);
 
@@ -813,22 +825,16 @@ empathy_connection_can_alias_personas (TpConnection *connection)
           TP_CONNECTION_STATUS_CONNECTED)
       return FALSE;
 
-  persona_store = FOLKS_PERSONA_STORE (
-      empathy_dup_persona_store_for_connection (connection));
-
-  retval = (folks_persona_store_get_can_alias_personas (persona_store) ==
-      FOLKS_MAYBE_BOOL_TRUE);
-
-  g_clear_object (&persona_store);
+  retval = check_writeable_property (connection, individual, "alias");
 
   return retval;
 }
 
 gboolean
-empathy_connection_can_group_personas (TpConnection *connection)
+empathy_connection_can_group_personas (TpConnection *connection,
+                                      FolksIndividual *individual)
 {
   gboolean retval;
-  FolksPersonaStore *persona_store;
 
   g_return_val_if_fail (TP_IS_CONNECTION (connection), FALSE);
 
@@ -836,13 +842,7 @@ empathy_connection_can_group_personas (TpConnection *connection)
           TP_CONNECTION_STATUS_CONNECTED)
       return FALSE;
 
-  persona_store = FOLKS_PERSONA_STORE (
-      empathy_dup_persona_store_for_connection (connection));
-
-  retval = (folks_persona_store_get_can_group_personas (persona_store) ==
-      FOLKS_MAYBE_BOOL_TRUE);
-
-  g_clear_object (&persona_store);
+  retval = check_writeable_property (connection, individual, "groups");
 
   return retval;
 }
@@ -992,3 +992,206 @@ empathy_account_has_uri_scheme_tel (TpAccount *account)
 
   return FALSE;
 }
+
+/* Return the TpContact on @conn associated with @individual, if any */
+TpContact *
+empathy_get_tp_contact_for_individual (FolksIndividual *individual,
+    TpConnection *conn)
+{
+  TpContact *contact = NULL;
+  GeeSet *personas;
+  GeeIterator *iter;
+
+  personas = folks_individual_get_personas (individual);
+  iter = gee_iterable_iterator (GEE_ITERABLE (personas));
+  while (contact == NULL && gee_iterator_next (iter))
+    {
+      TpfPersona *persona = gee_iterator_get (iter);
+      TpConnection *contact_conn;
+      TpContact *contact_cur = NULL;
+
+      if (TPF_IS_PERSONA (persona))
+        {
+          contact_cur = tpf_persona_get_contact (persona);
+          if (contact_cur != NULL)
+            {
+              contact_conn = tp_contact_get_connection (contact_cur);
+
+              if (!tp_strdiff (tp_proxy_get_object_path (contact_conn),
+                    tp_proxy_get_object_path (conn)))
+                contact = contact_cur;
+            }
+        }
+
+      g_clear_object (&persona);
+    }
+  g_clear_object (&iter);
+
+  return contact;
+}
+
+static gboolean
+properties_contains (gchar **list,
+                    gint length,
+                    const gchar *property)
+{
+  gint i;
+
+  for (i = 0; i < length; i++)
+    {
+      if (!tp_strdiff (list[i], property))
+       return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+check_writeable_property (TpConnection *connection,
+                         FolksIndividual *individual,
+                         gchar *property)
+{
+  gchar **properties;
+  gint prop_len;
+  gboolean retval = FALSE;
+  GeeSet *personas;
+  GeeIterator *iter;
+  FolksPersonaStore *persona_store;
+
+  persona_store = FOLKS_PERSONA_STORE (
+      empathy_dup_persona_store_for_connection (connection));
+
+  properties =
+    folks_persona_store_get_always_writeable_properties (persona_store,
+                                                        &prop_len);
+  retval = properties_contains (properties, prop_len, property);
+  if (retval == TRUE)
+    goto out;
+
+  /* Lets see if the Individual contains a Persona with the given property */
+  personas = folks_individual_get_personas (individual);
+  iter = gee_iterable_iterator (GEE_ITERABLE (personas));
+  while (!retval && gee_iterator_next (iter))
+    {
+      FolksPersona *persona = gee_iterator_get (iter);
+
+      properties =
+       folks_persona_get_writeable_properties (persona, &prop_len);
+      retval = properties_contains (properties, prop_len, property);
+
+      g_clear_object (&persona);
+
+      if (retval == TRUE)
+       break;
+    }
+  g_clear_object (&iter);
+
+out:
+  g_clear_object (&persona_store);
+  return retval;
+}
+
+/* Calculate whether the Individual can do audio or video calls.
+ * FIXME: We can remove this once libfolks has grown capabilities support
+ * again: bgo#626179. */
+void
+empathy_individual_can_audio_video_call (FolksIndividual *individual,
+    gboolean *can_audio_call,
+    gboolean *can_video_call,
+    EmpathyContact **out_contact)
+{
+  GeeSet *personas;
+  GeeIterator *iter;
+  gboolean can_audio = FALSE, can_video = FALSE;
+
+  personas = folks_individual_get_personas (individual);
+  iter = gee_iterable_iterator (GEE_ITERABLE (personas));
+  while (gee_iterator_next (iter))
+    {
+      FolksPersona *persona = gee_iterator_get (iter);
+      TpContact *tp_contact;
+
+      if (!empathy_folks_persona_is_interesting (persona))
+        goto while_finish;
+
+      tp_contact = tpf_persona_get_contact (TPF_PERSONA (persona));
+      if (tp_contact != NULL)
+        {
+          EmpathyContact *contact;
+
+          contact = empathy_contact_dup_from_tp_contact (tp_contact);
+          empathy_contact_set_persona (contact, persona);
+
+          can_audio = can_audio || empathy_contact_get_capabilities (contact) &
+              EMPATHY_CAPABILITIES_AUDIO;
+          can_video = can_video || empathy_contact_get_capabilities (contact) &
+              EMPATHY_CAPABILITIES_VIDEO;
+
+          if (out_contact != NULL)
+            *out_contact = g_object_ref (contact);
+
+          g_object_unref (contact);
+        }
+
+while_finish:
+      g_clear_object (&persona);
+
+      if (can_audio && can_video)
+        break;
+    }
+
+  g_clear_object (&iter);
+
+  if (can_audio_call != NULL)
+    *can_audio_call = can_audio;
+
+  if (can_video_call != NULL)
+    *can_video_call = can_video;
+}
+
+gboolean
+empathy_sasl_channel_supports_mechanism (TpChannel *channel,
+    const gchar *mechanism)
+{
+  GHashTable *props;
+  const gchar * const *available_mechanisms;
+
+  props = tp_channel_borrow_immutable_properties (channel);
+  available_mechanisms = tp_asv_get_boxed (props,
+      TP_PROP_CHANNEL_INTERFACE_SASL_AUTHENTICATION_AVAILABLE_MECHANISMS,
+      G_TYPE_STRV);
+
+  return tp_strv_contains (available_mechanisms, mechanism);
+}
+
+FolksIndividual *
+empathy_create_individual_from_tp_contact (TpContact *contact)
+{
+  TpAccount *account;
+  TpConnection *connection;
+  TpfPersonaStore *store;
+  GeeSet *personas;
+  TpfPersona *persona;
+  FolksIndividual *individual;
+
+  connection = tp_contact_get_connection (contact);
+  account = tp_connection_get_account (connection);
+
+  store = tpf_persona_store_new (account);
+
+  personas = GEE_SET (
+      gee_hash_set_new (FOLKS_TYPE_PERSONA, g_object_ref, g_object_unref,
+      g_direct_hash, g_direct_equal));
+
+  persona = tpf_persona_new (contact, store);
+
+  gee_collection_add (GEE_COLLECTION (personas), persona);
+
+  individual = folks_individual_new (personas);
+
+  g_clear_object (&persona);
+  g_clear_object (&personas);
+  g_object_unref (store);
+
+  return individual;
+}