]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-tp-call.c
Merge branch 'sasl'
[empathy.git] / libempathy / empathy-tp-call.c
index 31b4fe9e47e4a856e7bf710a2502b0e82253c5a1..1a53de65d51299d1638edaf1c7719bbfe0830fba 100644 (file)
@@ -25,6 +25,7 @@
 #include <telepathy-glib/proxy-subclass.h>
 #include <telepathy-glib/dbus.h>
 #include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/util.h>
 
 #include "empathy-tp-call.h"
 #include "empathy-tp-contact-factory.h"
@@ -38,6 +39,7 @@
 typedef struct
 {
   gboolean dispose_has_run;
+  TpAccount *account;
   TpChannel *channel;
   EmpathyContact *contact;
   gboolean is_incoming;
@@ -59,9 +61,9 @@ static guint signals[LAST_SIGNAL] = {0};
 enum
 {
   PROP_0,
+  PROP_ACCOUNT,
   PROP_CHANNEL,
   PROP_CONTACT,
-  PROP_IS_INCOMING,
   PROP_STATUS,
   PROP_AUDIO_STREAM,
   PROP_VIDEO_STREAM
@@ -264,7 +266,7 @@ tp_call_request_streams_for_capabilities (EmpathyTpCall *call,
 }
 
 static void
-tp_call_got_contact_cb (EmpathyTpContactFactory *factory,
+tp_call_got_contact_cb (TpConnection            *connection,
                         EmpathyContact          *contact,
                         const GError            *error,
                         gpointer                 user_data,
@@ -279,11 +281,14 @@ tp_call_got_contact_cb (EmpathyTpContactFactory *factory,
     }
 
   priv->contact = g_object_ref (contact);
-  priv->is_incoming = TRUE;
-  priv->status = EMPATHY_TP_CALL_STATUS_PENDING;
-  g_object_notify (G_OBJECT (call), "is-incoming");
+
+  if (priv->status < EMPATHY_TP_CALL_STATUS_PENDING)
+    {
+      priv->status = EMPATHY_TP_CALL_STATUS_PENDING;
+      g_object_notify (G_OBJECT (call), "status");
+    }
+
   g_object_notify (G_OBJECT (call), "contact");
-  g_object_notify (G_OBJECT (call), "status");
 }
 
 static void
@@ -301,19 +306,6 @@ tp_call_update_status (EmpathyTpCall *call)
   tp_intset_iter_init (&iter, set);
   while (tp_intset_iter_next (&iter))
     {
-      if (priv->contact == NULL && iter.element != self_handle)
-        {
-          EmpathyTpContactFactory *factory;
-          TpConnection *connection;
-
-          /* We found the remote contact */
-          connection = tp_channel_borrow_connection (priv->channel);
-          factory = empathy_tp_contact_factory_dup_singleton (connection);
-          empathy_tp_contact_factory_get_from_handle (factory, iter.element,
-              tp_call_got_contact_cb, NULL, NULL, G_OBJECT (call));
-          g_object_unref (factory);
-        }
-
       if (priv->status == EMPATHY_TP_CALL_STATUS_PENDING &&
           ((priv->is_incoming && iter.element == self_handle) ||
            (!priv->is_incoming && iter.element != self_handle)))
@@ -326,30 +318,6 @@ tp_call_update_status (EmpathyTpCall *call)
   g_object_unref (call);
 }
 
-void
-empathy_tp_call_to (EmpathyTpCall *call, EmpathyContact *contact,
-  gboolean audio, gboolean video)
-{
-  EmpathyTpCallPriv *priv = GET_PRIV (call);
-  EmpathyCapabilities capabilities = 0;
-
-  g_assert (audio || video);
-
-  priv->contact = g_object_ref (contact);
-  priv->is_incoming = FALSE;
-  priv->status = EMPATHY_TP_CALL_STATUS_PENDING;
-  g_object_notify (G_OBJECT (call), "is-incoming");
-  g_object_notify (G_OBJECT (call), "contact");
-  g_object_notify (G_OBJECT (call), "status");
-
-  if (video)
-    capabilities |= EMPATHY_CAPABILITIES_VIDEO;
-  if (audio)
-    capabilities |= EMPATHY_CAPABILITIES_AUDIO;
-
-  tp_call_request_streams_for_capabilities (call, capabilities);
-}
-
 static void
 tp_call_channel_invalidated_cb (TpChannel     *channel,
                                 GQuark         domain,
@@ -433,10 +401,19 @@ tp_call_constructor (GType type,
   tp_cli_channel_type_streamed_media_call_list_streams (priv->channel, -1,
       tp_call_request_streams_cb, NULL, NULL, G_OBJECT (call));
 
+  /* Is the call incoming? */
+  priv->is_incoming = !tp_channel_get_requested (priv->channel);
+
+  /* Get the remote contact */
+  empathy_tp_contact_factory_get_from_handle (
+      tp_channel_borrow_connection (priv->channel),
+      tp_channel_get_handle (priv->channel, NULL), tp_call_got_contact_cb,
+      NULL, NULL, object);
+
   /* Update status when members changes */
   tp_call_update_status (call);
-  g_signal_connect_swapped (priv->channel, "group-members-changed",
-      G_CALLBACK (tp_call_update_status), call);
+  tp_g_signal_connect_object (priv->channel, "group-members-changed",
+      G_CALLBACK (tp_call_update_status), call, G_CONNECT_SWAPPED);
 
   return object;
 }
@@ -464,6 +441,8 @@ tp_call_dispose (GObject *object)
   if (priv->contact != NULL)
       g_object_unref (priv->contact);
 
+  tp_clear_object (&priv->account);
+
   if (G_OBJECT_CLASS (empathy_tp_call_parent_class)->dispose)
     G_OBJECT_CLASS (empathy_tp_call_parent_class)->dispose (object);
 }
@@ -491,6 +470,9 @@ tp_call_set_property (GObject *object,
 
   switch (prop_id)
     {
+    case PROP_ACCOUNT:
+      priv->account = g_value_dup_object (value);
+      break;
     case PROP_CHANNEL:
       priv->channel = g_value_dup_object (value);
       break;
@@ -510,15 +492,15 @@ tp_call_get_property (GObject *object,
 
   switch (prop_id)
     {
+    case PROP_ACCOUNT:
+      g_value_set_object (value, priv->channel);
+      break;
     case PROP_CHANNEL:
       g_value_set_object (value, priv->channel);
       break;
     case PROP_CONTACT:
       g_value_set_object (value, priv->contact);
       break;
-    case PROP_IS_INCOMING:
-      g_value_set_boolean (value, priv->is_incoming);
-      break;
     case PROP_STATUS:
       g_value_set_uint (value, priv->status);
       break;
@@ -547,27 +529,33 @@ empathy_tp_call_class_init (EmpathyTpCallClass *klass)
 
   g_type_class_add_private (klass, sizeof (EmpathyTpCallPriv));
 
+  g_object_class_install_property (object_class, PROP_ACCOUNT,
+      g_param_spec_object ("account", "TpAccount", "TpAccount",
+      TP_TYPE_ACCOUNT,
+      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+      G_PARAM_STATIC_STRINGS));
+
   g_object_class_install_property (object_class, PROP_CHANNEL,
       g_param_spec_object ("channel", "channel", "channel",
       TP_TYPE_CHANNEL,
       G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
       G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
+
   g_object_class_install_property (object_class, PROP_CONTACT,
       g_param_spec_object ("contact", "Call contact", "Call contact",
       EMPATHY_TYPE_CONTACT,
       G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
-  g_object_class_install_property (object_class, PROP_IS_INCOMING,
-      g_param_spec_boolean ("is-incoming", "Is media stream incoming",
-      "Is media stream incoming", FALSE, G_PARAM_READABLE |
-      G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
+
   g_object_class_install_property (object_class, PROP_STATUS,
       g_param_spec_uint ("status", "Call status",
       "Call status", 0, 255, 0, G_PARAM_READABLE | G_PARAM_STATIC_NICK |
       G_PARAM_STATIC_BLURB));
+
   g_object_class_install_property (object_class, PROP_AUDIO_STREAM,
       g_param_spec_pointer ("audio-stream", "Audio stream data",
       "Audio stream data",
       G_PARAM_READABLE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
+
   g_object_class_install_property (object_class, PROP_VIDEO_STREAM,
       g_param_spec_pointer ("video-stream", "Video stream data",
       "Video stream data",
@@ -608,11 +596,14 @@ empathy_tp_call_init (EmpathyTpCall *call)
 }
 
 EmpathyTpCall *
-empathy_tp_call_new (TpChannel *channel)
+empathy_tp_call_new (TpAccount *account,
+    TpChannel *channel)
 {
+  g_return_val_if_fail (TP_IS_ACCOUNT (account), NULL);
   g_return_val_if_fail (TP_IS_CHANNEL (channel), NULL);
 
   return g_object_new (EMPATHY_TYPE_TP_CALL,
+      "account", account,
       "channel", channel,
       NULL);
 }
@@ -626,7 +617,9 @@ empathy_tp_call_accept_incoming_call (EmpathyTpCall *call)
 
   g_return_if_fail (EMPATHY_IS_TP_CALL (call));
   g_return_if_fail (priv->status == EMPATHY_TP_CALL_STATUS_PENDING);
-  g_return_if_fail (priv->is_incoming);
+
+  if (!priv->is_incoming)
+    return;
 
   DEBUG ("Accepting incoming call");
 
@@ -778,21 +771,8 @@ const gchar *
 empathy_tp_call_get_connection_manager (EmpathyTpCall *self)
 {
   EmpathyTpCallPriv *priv = GET_PRIV (self);
-  TpConnection *conn;
-  TpAccount *account;
 
-  if (priv->channel == NULL)
-    return NULL;
-
-  conn = tp_channel_borrow_connection (priv->channel);
-  if (conn == NULL)
-    return NULL;
-
-  account = empathy_get_account_for_connection (conn);
-  if (account == NULL)
-    return NULL;
-
-  return tp_account_get_connection_manager (account);
+  return tp_account_get_connection_manager (priv->account);
 }
 
 gboolean
@@ -816,3 +796,60 @@ empathy_tp_call_has_initial_video (EmpathyTpCall *self)
   g_hash_table_unref (props);
   return initial_video;
 }
+
+static void
+leave_remove_members_cb (TpChannel *proxy,
+    const GError *error,
+    gpointer user_data,
+    GObject *weak_object)
+{
+  EmpathyTpCall *self = user_data;
+
+  if (error == NULL)
+    return;
+
+  DEBUG ("RemoveMembers failed (%s); closing the channel", error->message);
+  empathy_tp_call_close (self);
+}
+
+void
+empathy_tp_call_leave (EmpathyTpCall *self)
+{
+  EmpathyTpCallPriv *priv = GET_PRIV (self);
+  TpHandle self_handle;
+  GArray array = { (gchar *) &self_handle, 1 };
+
+  if (!tp_proxy_has_interface_by_id (priv->channel,
+        TP_IFACE_QUARK_CHANNEL_INTERFACE_GROUP))
+    {
+      empathy_tp_call_close (self);
+      return;
+    }
+
+  self_handle = tp_channel_group_get_self_handle (priv->channel);
+  if (self_handle == 0)
+    {
+      /* we are not member of the channel */
+      empathy_tp_call_close (self);
+      return;
+    }
+
+  tp_cli_channel_interface_group_call_remove_members (priv->channel, -1, &array,
+      "", leave_remove_members_cb, self, NULL, G_OBJECT (self));
+}
+
+EmpathyTpCallStatus
+empathy_tp_call_get_status (EmpathyTpCall *self)
+{
+  EmpathyTpCallPriv *priv = GET_PRIV (self);
+
+  return priv->status;
+}
+
+TpAccount *
+empathy_tp_call_get_account (EmpathyTpCall *self)
+{
+  EmpathyTpCallPriv *priv = GET_PRIV (self);
+
+  return priv->account;
+}