changeset 23801:43b3b9ff6028

Added better Farsight error handling. Fixes several crash bugs related to missing GStreamer/Farsight plugins.
author Mike Ruprecht <maiku@soc.pidgin.im>
date Tue, 27 May 2008 02:24:03 +0000
parents 4b9b265a8100
children 5f4807116f8c
files libpurple/media.c libpurple/media.h libpurple/mediamanager.c libpurple/protocols/jabber/jabber.c pidgin/gtkconv.c pidgin/gtkmedia.c
diffstat 6 files changed, 82 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/media.c	Sun May 25 04:01:44 2008 +0000
+++ b/libpurple/media.c	Tue May 27 02:24:03 2008 +0000
@@ -710,7 +710,7 @@
 	gst_element_set_state(pipeline, GST_STATE_PLAYING);
 }
 
-static void
+static gboolean
 purple_media_add_stream_internal(PurpleMedia *media, FsSession **session, GList **streams,
 				 GstElement *src, const gchar *who, FsMediaType type,
 				 FsStreamDirection type_direction, const gchar *transmitter)
@@ -724,7 +724,18 @@
 	FsSession *s = NULL;
 
 	if (!*session) {
-		*session = fs_conference_new_session(media->priv->conference, type, NULL);
+		GError *err = NULL;
+		*session = fs_conference_new_session(media->priv->conference, type, &err);
+
+		if (err != NULL) {
+			purple_debug_error("media", "Error creating session: %s\n", err->message);
+			g_error_free(err);
+			purple_conv_present_error(who,
+						  purple_connection_get_account(purple_media_get_connection(media)),
+						  _("Error creating session."));
+			return FALSE;
+		}
+
 		if (src) {
 			GstPad *sinkpad;
 			GstPad *srcpad;
@@ -782,9 +793,11 @@
 		/* change direction */
 		g_object_set(stream, "direction", type_direction, NULL);
 	}
+
+	return TRUE;
 }
 
-void
+gboolean
 purple_media_add_stream(PurpleMedia *media, const gchar *who,
 			PurpleMediaStreamType type,
 			const gchar *transmitter)
@@ -801,11 +814,13 @@
 		else
 			type_direction = FS_DIRECTION_NONE;
 
-		purple_media_add_stream_internal(media, &media->priv->audio_session,
-						 &media->priv->audio_streams,
-				 		 media->priv->audio_src, who,
-						 FS_MEDIA_TYPE_AUDIO, type_direction,
-						 transmitter);
+		if (!purple_media_add_stream_internal(media, &media->priv->audio_session,
+						      &media->priv->audio_streams,
+				 		      media->priv->audio_src, who,
+						      FS_MEDIA_TYPE_AUDIO, type_direction,
+						      transmitter)) {
+			return FALSE;
+		}
 	}
 	if (type & PURPLE_MEDIA_VIDEO) {
 		if (type & PURPLE_MEDIA_SEND_VIDEO && type & PURPLE_MEDIA_RECV_VIDEO)
@@ -817,12 +832,15 @@
 		else
 			type_direction = FS_DIRECTION_NONE;
 
-		purple_media_add_stream_internal(media, &media->priv->video_session,
-						 &media->priv->video_streams,
-				 		 media->priv->video_src, who,
-						 FS_MEDIA_TYPE_VIDEO, type_direction,
-						 transmitter);
+		if (!purple_media_add_stream_internal(media, &media->priv->video_session,
+						      &media->priv->video_streams,
+				 		      media->priv->video_src, who,
+						      FS_MEDIA_TYPE_VIDEO, type_direction,
+						      transmitter)) {
+			return FALSE;
+		}
 	}
+	return TRUE;
 }
 
 void
--- a/libpurple/media.h	Sun May 25 04:01:44 2008 +0000
+++ b/libpurple/media.h	Tue May 27 02:24:03 2008 +0000
@@ -113,7 +113,7 @@
 
 void purple_media_audio_init_recv(GstElement **recvbin, GstElement **recvlevel);
 
-void purple_media_add_stream(PurpleMedia *media, const gchar *who,
+gboolean purple_media_add_stream(PurpleMedia *media, const gchar *who,
 			     PurpleMediaStreamType type, const gchar *transmitter);
 void purple_media_remove_stream(PurpleMedia *media, const gchar *who, PurpleMediaStreamType type);
 
--- a/libpurple/mediamanager.c	Sun May 25 04:01:44 2008 +0000
+++ b/libpurple/mediamanager.c	Tue May 27 02:24:03 2008 +0000
@@ -133,13 +133,22 @@
 				  const char *conference_type,
 				  const char *remote_user)
 {
+	PurpleMedia *media;
 	FsConference *conference = FS_CONFERENCE(gst_element_factory_make(conference_type, NULL));
+	GstStateChangeReturn ret = gst_element_set_state(GST_ELEMENT(conference), GST_STATE_READY);
 
-	PurpleMedia *media = PURPLE_MEDIA(g_object_new(purple_media_get_type(),
-					  "screenname", remote_user,
-					  "connection", gc, 
-					  "farsight-conference", conference,
-					  NULL));
+	if (ret == GST_STATE_CHANGE_FAILURE) {
+		purple_conv_present_error(remote_user,
+					  purple_connection_get_account(gc),
+					  _("Error creating conference."));
+		return NULL;
+	}
+
+	media = PURPLE_MEDIA(g_object_new(purple_media_get_type(),
+			     "screenname", remote_user,
+			     "connection", gc, 
+			     "farsight-conference", conference,
+			     NULL));
 	manager->priv->medias = g_list_append(manager->priv->medias, media);
 	g_signal_emit(manager, purple_media_manager_signals[INIT_MEDIA], 0, media);
 	return media;
--- a/libpurple/protocols/jabber/jabber.c	Sun May 25 04:01:44 2008 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Tue May 27 02:24:03 2008 +0000
@@ -2484,15 +2484,25 @@
 	}
 }
 
-static void
+static gboolean
 jabber_initiate_media_internal(JingleSession *session, const char *initiator, const char *remote_jid)
 {
 	PurpleMedia *media = NULL;
 
 	media = purple_media_manager_create_media(purple_media_manager_get(), 
 						  session->js->gc, "fsrtpconference", remote_jid);
+
+	if (!media) {
+		purple_debug_error("jabber", "Couldn't create fsrtpconference\n");
+		return FALSE;
+	}
+
 	/* this will need to be changed to "nice" once the libnice transmitter is finished */
-	purple_media_add_stream(media, remote_jid, PURPLE_MEDIA_AUDIO, "rawudp");
+	if (!purple_media_add_stream(media, remote_jid, PURPLE_MEDIA_AUDIO, "rawudp")) {
+		purple_debug_error("jabber", "Couldn't create audio stream\n");
+		purple_media_reject(media);
+		return FALSE;
+	}
 
 	jabber_jingle_session_set_remote_jid(session, remote_jid);
 	jabber_jingle_session_set_initiator(session, initiator);
@@ -2511,6 +2521,8 @@
 				 G_CALLBACK(jabber_session_candidate_pair_established), session);
 
 	purple_media_ready(media);
+
+	return TRUE;
 }
 
 static void
@@ -2581,7 +2593,12 @@
 	/* set ourselves as initiator */
 	me = g_strdup_printf("%s@%s/%s", js->user->node, js->user->domain, js->user->resource);
 
-	jabber_initiate_media_internal(session, me, jid);
+	if (!jabber_initiate_media_internal(session, me, jid)) {
+		g_free(jid);
+		g_free(me);
+		jabber_jingle_session_destroy(session);
+		return NULL;
+	}
 
 	g_free(jid);
 	g_free(me);
@@ -2717,6 +2734,11 @@
 	const char *sid = xmlnode_get_attrib(jingle, "sid");
 	JingleSession *session = jabber_jingle_session_find_by_id(js, sid);
 
+	if(!session) {
+		purple_debug_error("jabber", "jabber_handle_session_terminate couldn't find session\n");
+		return;
+	}
+
 	xmlnode_set_attrib(result->node, "to",
 			jabber_jingle_session_get_remote_jid(session));
 	xmlnode_set_attrib(result->node, "id", xmlnode_get_attrib(packet, "id"));
@@ -2831,7 +2853,12 @@
 		return;
 	}
 
-	jabber_initiate_media_internal(session, initiator, initiator);
+	if (!jabber_initiate_media_internal(session, initiator, initiator)) {
+		purple_debug_error("jabber", "Couldn't start media session with %s\n", initiator);
+		jabber_jingle_session_destroy(session);
+		/* we should create an error iq here */
+		return;
+	}
 
 	codecs = jabber_jingle_get_codecs(description);
 
--- a/pidgin/gtkconv.c	Sun May 25 04:01:44 2008 +0000
+++ b/pidgin/gtkconv.c	Tue May 27 02:24:03 2008 +0000
@@ -7694,7 +7694,8 @@
 							purple_conversation_get_name(conv),
 							PURPLE_MEDIA_RECV_AUDIO & PURPLE_MEDIA_SEND_AUDIO);
 
-	purple_media_wait(media);
+	if (media)
+		purple_media_wait(media);
 }
 
 static void
--- a/pidgin/gtkmedia.c	Sun May 25 04:01:44 2008 +0000
+++ b/pidgin/gtkmedia.c	Tue May 27 02:24:03 2008 +0000
@@ -228,7 +228,9 @@
 	gulong handler_id = g_signal_handler_find(G_OBJECT(gst_pipeline_get_bus(GST_PIPELINE(element))),
 						  G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, 0, 0, 
 						  NULL, G_CALLBACK(level_message_cb), gtkmedia);
-	g_signal_handler_disconnect(G_OBJECT(gst_pipeline_get_bus(GST_PIPELINE(element))), handler_id);
+	if (handler_id)
+		g_signal_handler_disconnect(G_OBJECT(gst_pipeline_get_bus(GST_PIPELINE(element))),
+					    handler_id);
 }
 
 static void