[telepathy-gabble/master] Move CallState code to media-channel-hold.c

Will Thompson will.thompson at collabora.co.uk
Tue Apr 14 04:28:53 PDT 2009


---
 src/media-channel-hold.c     |  173 +++++++++++++++++++++++++++++++++++++-----
 src/media-channel-internal.h |    9 ++-
 src/media-channel.c          |  125 +-----------------------------
 3 files changed, 163 insertions(+), 144 deletions(-)

diff --git a/src/media-channel-hold.c b/src/media-channel-hold.c
index ffa980b..509a9c3 100644
--- a/src/media-channel-hold.c
+++ b/src/media-channel-hold.c
@@ -28,6 +28,10 @@
 #include "debug.h"
 #include "util.h"
 
+/*
+ * Implementation of Channel.Interface.Hold, which deals with placing the peer
+ * on and off hold.
+ */
 
 static void
 stream_hold_state_changed (GabbleMediaStream *stream G_GNUC_UNUSED,
@@ -193,25 +197,6 @@ gabble_media_channel_hold_stream_closed (GabbleMediaChannel *chan,
 }
 
 
-/* Called by construct_stream to allow the Hold code to hook itself up to a new
- * stream.
- */
-void
-gabble_media_channel_hold_new_stream (GabbleMediaChannel *chan,
-    GabbleMediaStream *stream)
-{
-  GObject *chan_o = (GObject *) chan;
-
-  gabble_signal_connect_weak (stream, "unhold-failed",
-      (GCallback) stream_unhold_failed, chan_o);
-  gabble_signal_connect_weak (stream, "notify::local-hold",
-      (GCallback) stream_hold_state_changed, chan_o);
-
-  /* A stream being added might cause the "total" hold state to change */
-  stream_hold_state_changed (stream, NULL, chan);
-}
-
-
 /* Implements RequestHold on Telepathy.Channel.Interface.Hold */
 static void
 gabble_media_channel_request_hold (TpSvcChannelInterfaceHold *iface,
@@ -297,3 +282,153 @@ gabble_media_channel_hold_iface_init (gpointer g_iface,
   IMPLEMENT(request_hold);
 #undef IMPLEMENT
 }
+
+
+/*
+ * Implementation of Channel.Interface.CallState, which indicates call states
+ * from the peer (such as being put on or off hold, or that the peer's client
+ * is ringing.
+ */
+
+static TpChannelCallStateFlags
+jingle_remote_state_to_csf (JingleRtpRemoteState state)
+{
+  switch (state)
+    {
+    case JINGLE_RTP_REMOTE_STATE_ACTIVE:
+    /* FIXME: we should be able to expose <mute/> through CallState */
+    case JINGLE_RTP_REMOTE_STATE_MUTE:
+      return 0;
+    case JINGLE_RTP_REMOTE_STATE_RINGING:
+      return TP_CHANNEL_CALL_STATE_RINGING;
+    case JINGLE_RTP_REMOTE_STATE_HOLD:
+      return TP_CHANNEL_CALL_STATE_HELD;
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+
+static void
+remote_state_changed_cb (GabbleJingleMediaRtp *rtp,
+    GParamSpec *pspec G_GNUC_UNUSED,
+    GabbleMediaChannel *self)
+{
+  GabbleMediaChannelPrivate *priv = self->priv;
+  JingleRtpRemoteState state = gabble_jingle_media_rtp_get_remote_state (rtp);
+  TpChannelCallStateFlags csf = 0;
+
+  DEBUG ("Content %p's state changed to %u (current channel state: %u)", rtp,
+      state, priv->remote_state);
+
+  if (state == priv->remote_state)
+    {
+      DEBUG ("already in that state");
+      return;
+    }
+
+  if (state > priv->remote_state)
+    {
+      /* If this content's state is "more held" than the current aggregated level,
+       * move up to it.
+       */
+      DEBUG ("%u is more held than %u, moving up", state, priv->remote_state);
+      priv->remote_state = state;
+    }
+  else
+    {
+      /* This content is now less held than the current aggregated level; we
+       * need to recalculate the highest hold level and see if it's changed.
+       */
+      guint i = 0;
+
+      DEBUG ("%u less held than %u; recalculating", state, priv->remote_state);
+      state = JINGLE_RTP_REMOTE_STATE_ACTIVE;
+
+      for (i = 0; i < priv->streams->len; i++)
+        {
+          GabbleJingleMediaRtp *c = gabble_media_stream_get_content (
+                g_ptr_array_index (priv->streams, i));
+          JingleRtpRemoteState s = gabble_jingle_media_rtp_get_remote_state (c);
+
+          state = MAX (state, s);
+          DEBUG ("%p in state %u; high water mark %u", c, s, state);
+        }
+
+      if (priv->remote_state == state)
+        {
+          DEBUG ("no change");
+          return;
+        }
+
+      priv->remote_state = state;
+    }
+
+  csf = jingle_remote_state_to_csf (priv->remote_state);
+  DEBUG ("emitting CallStateChanged(%u, %u) (JingleRtpRemoteState %u)",
+      priv->session->peer, csf, priv->remote_state);
+  tp_svc_channel_interface_call_state_emit_call_state_changed (self,
+      priv->session->peer, csf);
+}
+
+
+/* Implements GetCallStates on Channel.Interface.CallState */
+static void
+gabble_media_channel_get_call_states (TpSvcChannelInterfaceCallState *iface,
+    DBusGMethodInvocation *context)
+{
+  GabbleMediaChannel *self = (GabbleMediaChannel *) iface;
+  GabbleMediaChannelPrivate *priv = self->priv;
+  JingleRtpRemoteState state = priv->remote_state;
+  GHashTable *states = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+  if (state != JINGLE_RTP_REMOTE_STATE_ACTIVE)
+    g_hash_table_insert (states, GUINT_TO_POINTER (priv->session->peer),
+        GUINT_TO_POINTER (jingle_remote_state_to_csf (state)));
+
+  tp_svc_channel_interface_call_state_return_from_get_call_states (context,
+      states);
+
+  g_hash_table_destroy (states);
+}
+
+
+void
+gabble_media_channel_call_state_iface_init (gpointer g_iface,
+    gpointer iface_data G_GNUC_UNUSED)
+{
+  TpSvcChannelInterfaceCallStateClass *klass = g_iface;
+
+#define IMPLEMENT(x) tp_svc_channel_interface_call_state_implement_##x (\
+    klass, gabble_media_channel_##x)
+  IMPLEMENT(get_call_states);
+#undef IMPLEMENT
+}
+
+
+/* Called by construct_stream to allow the Hold and CallState code to hook
+ * itself up to a new stream.
+ */
+void
+gabble_media_channel_hold_new_stream (GabbleMediaChannel *chan,
+    GabbleMediaStream *stream,
+    GabbleJingleMediaRtp *content)
+{
+  GObject *chan_o = (GObject *) chan;
+
+  gabble_signal_connect_weak (stream, "unhold-failed",
+      (GCallback) stream_unhold_failed, chan_o);
+  gabble_signal_connect_weak (stream, "notify::local-hold",
+      (GCallback) stream_hold_state_changed, chan_o);
+
+  /* A stream being added might cause the "total" hold state to change */
+  stream_hold_state_changed (stream, NULL, chan);
+
+  /* Watch the active/mute/held state of the corresponding content so we can
+   * keep the call state up to date, and call the callback once to pick up the
+   * current state of this content.
+   */
+  gabble_signal_connect_weak (content, "notify::remote-state",
+      (GCallback) remote_state_changed_cb, chan_o);
+  remote_state_changed_cb (content, NULL, chan);
+}
diff --git a/src/media-channel-internal.h b/src/media-channel-internal.h
index d7cd345..cc8f89e 100644
--- a/src/media-channel-internal.h
+++ b/src/media-channel-internal.h
@@ -71,12 +71,15 @@ struct _GabbleMediaChannelPrivate
 };
 
 void gabble_media_channel_hold_new_stream (GabbleMediaChannel *chan,
-    GabbleMediaStream *stream);
+    GabbleMediaStream *stream,
+    GabbleJingleMediaRtp *content);
 void gabble_media_channel_hold_stream_closed (GabbleMediaChannel *chan,
     GabbleMediaStream *stream);
 
-void
-gabble_media_channel_hold_iface_init (gpointer g_iface,
+void gabble_media_channel_hold_iface_init (gpointer g_iface,
+    gpointer iface_data G_GNUC_UNUSED);
+
+void gabble_media_channel_call_state_iface_init (gpointer g_iface,
     gpointer iface_data G_GNUC_UNUSED);
 
 G_END_DECLS
diff --git a/src/media-channel.c b/src/media-channel.c
index 8ec1904..05320fc 100644
--- a/src/media-channel.c
+++ b/src/media-channel.c
@@ -51,7 +51,6 @@
 
 #define MAX_STREAMS 99
 
-static void call_state_iface_init (gpointer, gpointer);
 static void channel_iface_init (gpointer, gpointer);
 static void media_signalling_iface_init (gpointer, gpointer);
 static void streamed_media_iface_init (gpointer, gpointer);
@@ -61,7 +60,7 @@ G_DEFINE_TYPE_WITH_CODE (GabbleMediaChannel, gabble_media_channel,
     G_TYPE_OBJECT,
     G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL, channel_iface_init);
     G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_CALL_STATE,
-      call_state_iface_init);
+      gabble_media_channel_call_state_iface_init);
     G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_GROUP,
       tp_group_mixin_iface_init);
     G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_HOLD,
@@ -2217,86 +2216,6 @@ stream_direction_changed_cb (GabbleMediaStream *stream,
       chan, id, direction, pending_send);
 }
 
-static TpChannelCallStateFlags
-jingle_remote_state_to_csf (JingleRtpRemoteState state)
-{
-  switch (state)
-    {
-    case JINGLE_RTP_REMOTE_STATE_ACTIVE:
-    /* FIXME: we should be able to expose <mute/> through CallState */
-    case JINGLE_RTP_REMOTE_STATE_MUTE:
-      return 0;
-    case JINGLE_RTP_REMOTE_STATE_RINGING:
-      return TP_CHANNEL_CALL_STATE_RINGING;
-    case JINGLE_RTP_REMOTE_STATE_HOLD:
-      return TP_CHANNEL_CALL_STATE_HELD;
-    default:
-      g_assert_not_reached ();
-    }
-}
-
-static void
-remote_state_changed_cb (GabbleJingleMediaRtp *rtp,
-    GParamSpec *pspec G_GNUC_UNUSED,
-    GabbleMediaChannel *self)
-{
-  GabbleMediaChannelPrivate *priv = self->priv;
-  JingleRtpRemoteState state = gabble_jingle_media_rtp_get_remote_state (rtp);
-  TpChannelCallStateFlags csf = 0;
-
-  DEBUG ("Content %p's state changed to %u (current channel state: %u)", rtp,
-      state, priv->remote_state);
-
-  if (state == priv->remote_state)
-    {
-      DEBUG ("already in that state");
-      return;
-    }
-
-  if (state > priv->remote_state)
-    {
-      /* If this content's state is "more held" than the current aggregated level,
-       * move up to it.
-       */
-      DEBUG ("%u is more held than %u, moving up", state, priv->remote_state);
-      priv->remote_state = state;
-    }
-  else
-    {
-      /* This content is now less held than the current aggregated level; we
-       * need to recalculate the highest hold level and see if it's changed.
-       */
-      guint i = 0;
-
-      DEBUG ("%u less held than %u; recalculating", state, priv->remote_state);
-      state = JINGLE_RTP_REMOTE_STATE_ACTIVE;
-
-      for (i = 0; i < priv->streams->len; i++)
-        {
-          GabbleJingleMediaRtp *c = gabble_media_stream_get_content (
-                g_ptr_array_index (priv->streams, i));
-          JingleRtpRemoteState s = gabble_jingle_media_rtp_get_remote_state (c);
-
-          state = MAX (state, s);
-          DEBUG ("%p in state %u; high water mark %u", c, s, state);
-        }
-
-      if (priv->remote_state == state)
-        {
-          DEBUG ("no change");
-          return;
-        }
-
-      priv->remote_state = state;
-    }
-
-  csf = jingle_remote_state_to_csf (priv->remote_state);
-  DEBUG ("emitting CallStateChanged(%u, %u) (JingleRtpRemoteState %u)",
-      priv->session->peer, csf, priv->remote_state);
-  tp_svc_channel_interface_call_state_emit_call_state_changed (self,
-      priv->session->peer, csf);
-}
-
 #define GTALK_CAPS \
   ( PRESENCE_CAP_GOOGLE_VOICE )
 
@@ -2393,14 +2312,6 @@ construct_stream (GabbleMediaChannel *chan,
   gabble_signal_connect_weak (stream, "notify::combined-direction",
       (GCallback) stream_direction_changed_cb, chan_o);
 
-  /* While we're here, watch the active/mute/held state of the corresponding
-   * content so we can keep the call state up to date, and call the callback
-   * once to pick up the current state of this content.
-   */
-  gabble_signal_connect_weak (c, "notify::remote-state",
-      (GCallback) remote_state_changed_cb, chan_o);
-  remote_state_changed_cb (GABBLE_JINGLE_MEDIA_RTP (c), NULL, chan);
-
   /* emit StreamAdded */
   mtype = gabble_media_stream_get_media_type (stream);
 
@@ -2414,7 +2325,8 @@ construct_stream (GabbleMediaChannel *chan,
    * signal handler, so we call the handler manually to pick it up. */
   stream_direction_changed_cb (stream, NULL, chan);
 
-  gabble_media_channel_hold_new_stream (chan, stream);
+  gabble_media_channel_hold_new_stream (chan, stream,
+      GABBLE_JINGLE_MEDIA_RTP (c));
 
   if (priv->ready)
     {
@@ -2618,25 +2530,6 @@ _gabble_media_channel_caps_to_typeflags (GabblePresenceCapabilities caps)
 }
 
 static void
-gabble_media_channel_get_call_states (TpSvcChannelInterfaceCallState *iface,
-                                      DBusGMethodInvocation *context)
-{
-  GabbleMediaChannel *self = (GabbleMediaChannel *) iface;
-  GabbleMediaChannelPrivate *priv = self->priv;
-  JingleRtpRemoteState state = priv->remote_state;
-  GHashTable *states = g_hash_table_new (g_direct_hash, g_direct_equal);
-
-  if (state != JINGLE_RTP_REMOTE_STATE_ACTIVE)
-    g_hash_table_insert (states, GUINT_TO_POINTER (priv->session->peer),
-        GUINT_TO_POINTER (jingle_remote_state_to_csf (state)));
-
-  tp_svc_channel_interface_call_state_return_from_get_call_states (context,
-      states);
-
-  g_hash_table_destroy (states);
-}
-
-static void
 _emit_new_stream (GabbleMediaChannel *chan,
                   GabbleMediaStream *stream)
 {
@@ -2778,18 +2671,6 @@ media_signalling_iface_init (gpointer g_iface, gpointer iface_data)
 }
 
 static void
-call_state_iface_init (gpointer g_iface,
-                       gpointer iface_data G_GNUC_UNUSED)
-{
-  TpSvcChannelInterfaceCallStateClass *klass = g_iface;
-
-#define IMPLEMENT(x) tp_svc_channel_interface_call_state_implement_##x (\
-    klass, gabble_media_channel_##x)
-  IMPLEMENT(get_call_states);
-#undef IMPLEMENT
-}
-
-static void
 session_handler_iface_init (gpointer g_iface, gpointer iface_data)
 {
   TpSvcMediaSessionHandlerClass *klass =
-- 
1.5.6.5




More information about the telepathy-commits mailing list