diff --git a/hudson-sflphone-script.sh b/hudson-sflphone-script.sh index 3cd75ab50037d7aeb13c501948e496f28c7f4cf1..a0b1ab68d1b99426cbeb8205cf90c1430f27b126 100755 --- a/hudson-sflphone-script.sh +++ b/hudson-sflphone-script.sh @@ -29,7 +29,7 @@ pushd sflphone-common/test rm -rf $XML_RESULTS make check # if at least one test failed, exit -./test --xml || exit 1 +CODECS_PATH="../src/audio/codecs" FAKE_PLUGIN_DIR="../src/plug-in/test/" FAKE_PLUGIN_NAME="../src/plug-in/test/libplugintest.so" ./test --xml || exit 1 popd # Compile the client diff --git a/sflphone-client-gnome/src/actions.c b/sflphone-client-gnome/src/actions.c index ff7ce9c15b498a9c6662f276eaa0ed3861395b55..4be631e4cd3c7bfccef393bcda5f3cb90e5245ec 100644 --- a/sflphone-client-gnome/src/actions.c +++ b/sflphone-client-gnome/src/actions.c @@ -547,8 +547,9 @@ sflphone_pick_up() calltree_update_call (history, selectedCall, NULL); // if instant messaging window is visible, create new tab (deleted automatically if not used) - if (im_window_is_visible()) + if (selectedCall->_im_widget && im_window_is_visible()) { im_widget_display ( (IMWidget **) (&selectedCall->_im_widget), NULL, selectedCall->_callID, NULL); + } dbus_accept (selectedCall); stop_notification(); @@ -1127,7 +1128,22 @@ sflphone_join_participant (const gchar* sel_callID, const gchar* drag_callID) void sflphone_add_participant (const gchar* callID, const gchar* confID) { - DEBUG ("sflphone add participant %s to conference %s", callID, confID); + GtkTreeIter iter; + callable_obj_t *call; + + DEBUG (">SFLphone: Add participant %s to conference %s", callID, confID); + + call = calllist_get_call(current_calls, callID); + if(call == NULL) { + ERROR("SFLphone: Error: Could not find call"); + return; + } + + set_timestamp(&call->_time_added); + + iter = calltree_get_gtkiter_from_id(history, (gchar *)confID); + + calltree_add_call(history, call, &iter); dbus_add_participant (callID, confID); } @@ -1353,11 +1369,11 @@ void sflphone_fill_conference_list (void) void sflphone_fill_history (void) { - gchar **entries, *current_entry; - callable_obj_t *history_entry; - callable_obj_t *call; + const gchar **entries, **history_entries; + gchar *current_entry; + callable_obj_t *history_call, *call; + conference_obj_t *history_conf, *conf; QueueElement *element; - conference_obj_t *conference_entry; guint i = 0, n = 0; DEBUG ("======================================================= SFLphone: Loading history"); @@ -1365,43 +1381,57 @@ void sflphone_fill_history (void) entries = dbus_get_history (); while (*entries) { - const gchar *delim = "|"; - gchar **ptr; - current_entry = *entries; + current_entry = (gchar *)*entries; DEBUG("============================================ entry: %s", current_entry); - // do something with key and value - create_history_entry_from_serialized_form (current_entry, &history_entry); + if(g_str_has_prefix(current_entry, "9999")) { + // create a conference entry + create_conference_history_entry_from_serialized(current_entry, &history_conf); + + conf = conferencelist_get(history, history_conf->_confID); + if(conf == NULL) { + conferencelist_add(history, history_conf); + } + else { + conf->_recordfile = g_strdup(history_conf->_recordfile); + } + } + else { + + // do something with key and value + create_history_entry_from_serialized_form (current_entry, &history_call); - // Add it and update the GUI - calllist_add_call (history, history_entry); + // Add it and update the GUI + calllist_add_call (history, history_call); - if(history_entry->_confID && g_strcmp0(history_entry->_confID, "") != 0) { - conference_obj_t *conf; + if(history_call->_confID && g_strcmp0(history_call->_confID, "") != 0) { - DEBUG("----------------- conf id: %s", history_entry->_confID); + DEBUG("----------------- conf id: %s", history_call->_confID); - // process conference - conf = conferencelist_get(history, history_entry->_confID); - if(conf == NULL) { - // conference does not exist yet, create it - create_new_conference(CONFERENCE_STATE_ACTIVE_ATACHED, history_entry->_confID, &conf); - conferencelist_add(history, conf); - } + // process conference + conf = conferencelist_get(history, history_call->_confID); + if(conf == NULL) { + // conference does not exist yet, create it + create_new_conference(CONFERENCE_STATE_ACTIVE_ATACHED, history_call->_confID, &conf); + conferencelist_add(history, conf); + } - conference_add_participant(history_entry->_callID, conf); + conference_add_participant(history_call->_callID, conf); - // conference start timestamp corespond to - if(conf->_time_start > history_entry->_time_added) { - conf->_time_start = history_entry->_time_added; - } + // conference start timestamp corespond to + if(conf->_time_start > history_call->_time_added) { + conf->_time_start = history_call->_time_added; + } + } } entries++; } + entries = history_entries; + // fill n = calllist_get_size(history); DEBUG("CALL SIZE: %d", n); @@ -1443,7 +1473,6 @@ void sflphone_save_history (void) g_hash_table_ref (result); size = calllist_get_size (history); - for (i = 0; i < size; i++) { current = calllist_get_nth (history, i); @@ -1470,6 +1499,20 @@ void sflphone_save_history (void) } } + size = conferencelist_get_size(history); + for(i = 0; i < size; i++) { + conf = conferencelist_get_nth(history, i); + if(conf == NULL) { + DEBUG("SFLphone: Error: Could not get %dth conference", i); + break; + } + value = serialize_history_conference_entry(conf); + key = convert_timestamp_to_gchar(conf->_time_start); + + g_hash_table_replace(result, (gpointer) key, + g_slist_append(g_hash_table_lookup(result, key), (gpointer) value)); + } + sflphone_order_history_hash_table(result, &ordered_result); gchar **testprnt = ordered_result; diff --git a/sflphone-client-gnome/src/callable_obj.c b/sflphone-client-gnome/src/callable_obj.c index 8cd5877b3cb955510485cdb76fbc45e5e7ff0094..267874fc0ab2cce59ea8359152d5194ca1e89b84 100644 --- a/sflphone-client-gnome/src/callable_obj.c +++ b/sflphone-client-gnome/src/callable_obj.c @@ -235,12 +235,12 @@ void create_new_call (callable_type_t type, call_state_t state, gchar* callID , obj->_peer_number = g_strdup (peer_number); obj->_peer_info = g_strdup (get_peer_info (peer_name, peer_number)); obj->_recordfile = NULL; + obj->_record_is_playing = FALSE; obj->_trsft_to = ""; set_timestamp (& (obj->_time_start)); set_timestamp (& (obj->_time_current)); set_timestamp (& (obj->_time_stop)); - // g_snprintf(obj->_timestr, 20, "00:00"); if (g_strcasecmp (callID, "") == 0) call_id = generate_call_id (); @@ -365,6 +365,7 @@ void create_history_entry_from_serialized_form (gchar *entry, callable_obj_t **c new_call->_confID = g_strdup(confID); new_call->_historyConfID = g_strdup(confID); new_call->_time_added = convert_gchar_to_timestamp(time_start); + new_call->_record_is_playing = FALSE; *call = new_call; } diff --git a/sflphone-client-gnome/src/callable_obj.h b/sflphone-client-gnome/src/callable_obj.h index 71e75aaffd0f723d57bd3561a49fff013e8a0974..34be817e23f9c78457e2580aad05d699142b1170 100644 --- a/sflphone-client-gnome/src/callable_obj.h +++ b/sflphone-client-gnome/src/callable_obj.h @@ -157,6 +157,12 @@ typedef struct { */ gchar *_recordfile; + /** + * This boolean value is used to determine if the audio file + * is currently played back. + */ + gboolean _record_is_playing; + /* Associated IM widget */ GtkWidget *_im_widget; diff --git a/sflphone-client-gnome/src/conference_obj.c b/sflphone-client-gnome/src/conference_obj.c index 07ae344ef69debaf3ca77a2a60147945e141093a..015365fc4dd3def6c4b55c40906393415ea0f232 100644 --- a/sflphone-client-gnome/src/conference_obj.c +++ b/sflphone-client-gnome/src/conference_obj.c @@ -76,6 +76,9 @@ void create_new_conference (conference_state_t state, const gchar* confID, confe new_conf->participant_list = NULL; new_conf->participant_number = NULL; + new_conf->_recordfile = NULL; + new_conf->_record_is_playing = FALSE; + set_conference_timestamp(&new_conf->_time_start); *conf = new_conf; @@ -128,6 +131,9 @@ void create_new_conference_from_details (const gchar *conf_id, GHashTable *detai new_conf->_state = CONFERENCE_STATE_HOLD_RECORD; } + new_conf->_recordfile = NULL; + new_conf->_record_is_playing = FALSE; + *conf = new_conf; } @@ -254,7 +260,7 @@ gchar *serialize_history_conference_entry(conference_obj_t *entry) DEBUG("Conference: Participant number: %s, concatenation: %s", tmp, participantstr); } - result = g_strconcat("2188", separator, + result = g_strconcat("9999", separator, participantstr, separator, // peer number peer_name, separator, time_start, separator, @@ -268,7 +274,7 @@ gchar *serialize_history_conference_entry(conference_obj_t *entry) return result; } -void create_conference_history_entry_from_serialized(gchar **ptr, conference_obj_t **conf) +void create_conference_history_entry_from_serialized(gchar *entry, conference_obj_t **conf) { history_state_t history_state = MISSED; gint token = 0; @@ -280,9 +286,12 @@ void create_conference_history_entry_from_serialized(gchar **ptr, conference_obj gchar *accountID = ""; gchar *recordfile = ""; const gchar *confID = ""; + gchar **ptr; + gchar *delim = "|"; DEBUG("Conference: Create a conference from serialized form"); + ptr = g_strsplit(entry, delim, 8); while(ptr != NULL && token < 8) { switch(token) { case 0: @@ -320,7 +329,7 @@ void create_conference_history_entry_from_serialized(gchar **ptr, conference_obj // create a new empty conference create_new_conference(state, confID, conf); - process_conference_participant_from_serialized(participant, *conf); + // process_conference_participant_from_serialized(participant, *conf); g_free(participant); } @@ -328,12 +337,7 @@ void create_conference_history_entry_from_serialized(gchar **ptr, conference_obj static void process_conference_participant_from_serialized(gchar *participant, conference_obj_t *conf) { gchar **ptr = NULL; - gchar **numberptr = NULL; gchar *delim = ";"; - gchar *delimnumber = ","; - gchar *numberaccount; - guint token = 0; - callable_obj_t *tmp_call = NULL; gint tok = 0; @@ -342,45 +346,6 @@ static void process_conference_participant_from_serialized(gchar *participant, c ptr = g_strsplit(participant, delim, 3); while(ptr != NULL && (tok < 2)) { gchar *call_id = NULL; -/* - gchar *phone_number = NULL; - gchar *account = NULL; - gchar *name = ""; - token = 0; - numberaccount = *ptr; - numberptr = g_strsplit(numberaccount, delimnumber, 2); -*/ -/* - while(numberptr != NULL && (token < 3)) { - switch(token) { - case 0: - phone_number = *numberptr; - break; - case 1: - call_id = *ptr; - break; - case 2: - account = *numberptr; - // remove the ";" character at the end of the account string - if(g_str_has_suffix(account, ";")) { - int len = strlen(account); - gchar *tmpchar = g_strdup(account); - g_strlcpy(account, tmpchar, len); - } - break; - default: - break; - } - token++; - numberptr++; - } -*/ - - // we should create call here and add it to the conference to be inserted in history - // create_new_call(HISTORY_ENTRY, CALL_STATE_DIALING, call_id, account, name, phone_number, &tmp_call); - // calllist_add_history_call(tmp_call); - // calllist_add_call(history, tmp_call); - // calllist_add_call(current_calls, tmp_call); conference_add_participant(call_id, conf); diff --git a/sflphone-client-gnome/src/conference_obj.h b/sflphone-client-gnome/src/conference_obj.h index a9523fc6191f3959fa189d7f72d56b076e8162a0..927db5a42d53a548ad3a3a681ca07f10b4c80e92 100644 --- a/sflphone-client-gnome/src/conference_obj.h +++ b/sflphone-client-gnome/src/conference_obj.h @@ -56,7 +56,6 @@ typedef enum { * This struct holds information about a conference. */ typedef struct { - conference_state_t _state; // The state of the call gchar *_confID; // The call ID gboolean _conference_secured; // the security state of the conference @@ -68,6 +67,7 @@ typedef struct { time_t _time_stop; time_t _time_current; gchar *_recordfile; + gboolean _record_is_playing; } conference_obj_t; void create_new_conference (conference_state_t, const gchar*, conference_obj_t **); @@ -86,6 +86,6 @@ void conference_participant_list_update (gchar**, conference_obj_t*); gchar *serialize_history_conference_entry(conference_obj_t *entry); -void create_conference_history_entry_from_serialized(gchar **, conference_obj_t **); +void create_conference_history_entry_from_serialized(gchar *, conference_obj_t **); #endif diff --git a/sflphone-client-gnome/src/contacts/calltree.c b/sflphone-client-gnome/src/contacts/calltree.c index ab6af26db272aa2ec1c4d334d62b0a4e54337adb..d7174bfb522652f6f21a572af97fea8d4606d915 100644 --- a/sflphone-client-gnome/src/contacts/calltree.c +++ b/sflphone-client-gnome/src/contacts/calltree.c @@ -34,13 +34,16 @@ #include <stdlib.h> #include <glib/gprintf.h> #include <eel-gconf-extensions.h> -#include <calllist.h> -#include <conferencelist.h> -#include <mainwindow.h> -#include <history.h> + +#include "dbus.h" +#include "calllist.h" +#include "conferencelist.h" +#include "mainwindow.h" +#include "history.h" +#include "calltree.h" #include "uimanager.h" #include "actions.h" -#include "../imwindow.h" +#include "imwindow.h" #include "searchbar.h" // Messages used in menu item @@ -295,7 +298,7 @@ row_activated (GtkTreeView *tree_view UNUSED, static void calltree_create_conf_from_participant_list(GSList *list) { - gchar **participant_list, participant_number; + gchar **participant_list; gint list_length = g_slist_length(list); gint i = 0; gint c = 0; @@ -326,7 +329,7 @@ calltree_create_conf_from_participant_list(GSList *list) { participant_list = (void *) realloc(participant_list, (c+1) *sizeof(void*)); *(participant_list+c) = NULL; - dbus_create_conf_from_participant_list(participant_list); + dbus_create_conf_from_participant_list((const gchar **)participant_list); } /* Catch cursor-activated signal. That is, when the entry is single clicked */ @@ -1050,7 +1053,6 @@ void calltree_add_call (calltab_t* tab, callable_obj_t * c, GtkTreeIter *parent) WARN ("CallTree: This widget doesn't exist - This is a bug in the application."); } - //Resize it if (pixbuf) { if (gdk_pixbuf_get_width (pixbuf) > 32 || gdk_pixbuf_get_height (pixbuf) > 32) { @@ -1442,7 +1444,7 @@ void calltree_remove_conference (calltab_t* tab, const conference_obj_t* conf, G void calltree_add_history_conference(conference_obj_t *conf) { GdkPixbuf *pixbuf = NULL; - gchar *description = "Conference: ", *date = "", *duration = ""; + gchar *description = "Conference: ", *date = ""; GtkTreeIter iter; gchar *call_id; callable_obj_t *call; @@ -1452,7 +1454,7 @@ void calltree_add_history_conference(conference_obj_t *conf) ERROR("CallTree: Error conference is NULL"); } - DEBUG("---------------------------------------------------------- CallTree: Add conference %s to history", conf->_confID); + DEBUG("CallTree: Add conference %s to history", conf->_confID); gtk_tree_store_prepend(history->store, &iter, NULL); @@ -1499,23 +1501,17 @@ void calltree_display (calltab_t *tab) /* case 1: we want to display the main calltree */ if (tab==current_calls) { - DEBUG ("CallTree: Display main tab"); - if (active_calltree==contacts) { gtk_toggle_tool_button_set_active ( (GtkToggleToolButton*) contactButton, FALSE); } else { gtk_toggle_tool_button_set_active ( (GtkToggleToolButton*) historyButton, FALSE); } - - // gtk_toggle_tool_button_set_active ((GtkToggleToolButton*)currentCallsButton, TRUE); - } /* case 2: we want to display the history */ else if (tab == history) { - DEBUG ("ConferenceList: Display history tab"); if (active_calltree==contacts) { @@ -1526,7 +1522,6 @@ void calltree_display (calltab_t *tab) } else if (tab==contacts) { - DEBUG ("CallTree: Display contact tab"); if (active_calltree==history) { @@ -1651,7 +1646,7 @@ static void drag_end_cb (GtkWidget * widget UNUSED, GdkDragContext * context UNU if (selected_call->_confID) { gtk_tree_path_up (spath); - gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &parent_conference, spath); + gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &parent_conference, spath); calltree_add_call (current_calls, selected_call, &parent_conference); } else { @@ -1718,7 +1713,7 @@ static void drag_end_cb (GtkWidget * widget UNUSED, GdkDragContext * context UNU selected_call->_historyConfID = NULL; } selected_call->_historyConfID = g_strdup(dragged_call_id); - sflphone_add_participant (selected_call_id, dragged_call_id); + sflphone_add_participant (selected_call_id, dragged_call_id); } else if (selected_type == A_CONFERENCE && dragged_type == A_CALL) { // dragged a conference on a single call @@ -1727,7 +1722,6 @@ static void drag_end_cb (GtkWidget * widget UNUSED, GdkDragContext * context UNU calltree_remove_conference (current_calls, conf, NULL); calltree_add_conference (current_calls, conf); - } else if (selected_type == A_CONFERENCE && dragged_type == A_CONFERENCE) { // dragged a conference on a conference @@ -1992,6 +1986,40 @@ static void menuitem_response( gchar *string ) // The create conference option will hide if tow call from the same conference are draged on each other gtk_widget_show(menu_items); - printf ("%s\n", string); + printf("%s\n", string); } +GtkTreeIter calltree_get_gtkiter_from_id(calltab_t *tab, gchar *id) +{ + GtkTreeIter iter; + GValue val; + GtkTreeModel *tree_model; + conference_obj_t *conf; + callable_obj_t *call; + + tree_model = GTK_TREE_MODEL(tab->store); + + gtk_tree_model_get_iter_first(tree_model, &iter); + + while(gtk_tree_model_iter_next(tree_model, &iter)) { + val.g_type = 0; + gtk_tree_model_get_value (tree_model, &iter, COLUMN_ACCOUNT_PTR, &val); + + if(gtk_tree_model_iter_has_child(tree_model, &iter)) { + conf = (conference_obj_t *) g_value_get_pointer (&val); + + if(g_strcmp0(conf->_confID, id) == 0) { + return iter; + } + } + else { + call = (callable_obj_t *) g_value_get_pointer(&val); + + if(g_strcmp0(call->_callID, id) == 0) { + return iter; + } + } + } + + return iter; +} diff --git a/sflphone-client-gnome/src/contacts/calltree.h b/sflphone-client-gnome/src/contacts/calltree.h index b13a43381e200be6587f2819232600cad549af19..641974da6fc3fdaebb4e7c88c80397960a97e285 100644 --- a/sflphone-client-gnome/src/contacts/calltree.h +++ b/sflphone-client-gnome/src/contacts/calltree.h @@ -122,4 +122,13 @@ row_activated (GtkTreeView *, GtkTreePath *, GtkTreeViewColumn *, void *); void calltree_update_clock(); +/** + * Get the iter to a row provided the callID/confID + * @param The calltab (current_calls, history, contacts) + * @param The callID/confID + * @return The + */ +GtkTreeIter +calltree_get_gtkiter_from_id(calltab_t *, gchar *); + #endif diff --git a/sflphone-client-gnome/src/contacts/conferencelist.c b/sflphone-client-gnome/src/contacts/conferencelist.c index ede9fd52882f12b2b0e88e4431ae3432f9e4d5a7..c7bf7a90e486302d73c83ae874f75eb029eb49be 100644 --- a/sflphone-client-gnome/src/contacts/conferencelist.c +++ b/sflphone-client-gnome/src/contacts/conferencelist.c @@ -83,7 +83,6 @@ conferencelist_clean_history(void) { conference_obj_t *conf; guint size = conferencelist_get_size(history); - guint i; DEBUG("ConferenceList: clean history"); @@ -189,7 +188,7 @@ conference_obj_t* conferencelist_get (calltab_t *tab, const gchar* conf_id) conference_obj_t* conferencelist_get_nth (calltab_t *tab, guint n) { - GList* c; + conference_obj_t *c; if(tab == NULL) { ERROR("ConferenceList: Error: Calltab is NULL"); @@ -203,7 +202,7 @@ conference_obj_t* conferencelist_get_nth (calltab_t *tab, guint n) return NULL; } - return (conference_obj_t*) c; + return c; } conference_obj_t *conferencelist_pop_head(calltab_t *tab) diff --git a/sflphone-client-gnome/src/dbus/callmanager-introspec.xml b/sflphone-client-gnome/src/dbus/callmanager-introspec.xml index 61ecf9a9c04677e304c316d9a986e62e9e317d1d..5c6591855eca01beeabf2f71dbc62aef93ef759c 100644 --- a/sflphone-client-gnome/src/dbus/callmanager-introspec.xml +++ b/sflphone-client-gnome/src/dbus/callmanager-introspec.xml @@ -340,6 +340,21 @@ </arg> </method> + <signal name="recordPlaybackFilepath" tp:name-for-bindings="recordPlaybackFilepath"> + <tp:docstring> + Once after starting recording for the first time, this signal is emited to + provide the recorded file path to client application. + </tp:docstring> + <arg type="s" name="callID" /> + <arg type="s" name="filepath"/> + </signal> + + <signal name="recordPlaybackStoped" tp:name-for-bindings="recordPlaybackStoped"> + <tp:docstring/> + <arg type="s" name="filepath" /> + </signal> + + <method name="getCallDetails" tp:name-for-bindings="getCallDetails"> <tp:docstring> Get all the details about a specific call. @@ -590,6 +605,20 @@ </tp:docstring> </arg> </method> + + <method name="startRecordedFilePlayback" tp:name-for-bindings="startRecordedFilePlayback"> + <tp:added version="0.9.14"/> + <tp:docstring> + </tp:docstring> + <arg type="s" name="filepath" direction="in"/> + <arg type="b" name="result" direction="out"/> + </method> + + <method name="stopRecordedFilePlayback" tp:name-for-bindings="stopRecordedFilePlayback"> + <tp:added version="0.9.14"/> + <tp:docstring/> + <arg type="s" name="filepath" direction="in"/> + </method> <signal name="sipCallStateChanged" tp:name-for-bindings="sipCallStateChanged"> <tp:docstring> diff --git a/sflphone-client-gnome/src/dbus/configurationmanager-introspec.xml b/sflphone-client-gnome/src/dbus/configurationmanager-introspec.xml index a136ae7b1d7c0ab5f94eca651955362bbfa05e4b..75f05227757e9819c3174a2477b848e3e101d9a3 100755 --- a/sflphone-client-gnome/src/dbus/configurationmanager-introspec.xml +++ b/sflphone-client-gnome/src/dbus/configurationmanager-introspec.xml @@ -628,7 +628,7 @@ </method> <method name="setAudioRingtoneDevice" tp:name-for-bindings="setAudioRingtoneDevice"> - <tp:docstring> + <tp:docstring> </tp:docstring> <arg type="i" name="index" direction="in"> <tp:docstring> @@ -690,6 +690,8 @@ <method name="setNoiseSuppressState" tp:name-for-bindings="setNoiseSuppressState"> <arg type="s" name="state" direction="in"> + <tp:docstring> + </tp:docstring> </arg> </method> @@ -1011,36 +1013,37 @@ <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="MapStringString"/> <tp:docstring> </tp:docstring> - <arg type="a{ss}" name="shortcutsMap" direction="in"> <tp:docstring> + <arg type="a{ss}" name="shortcutsMap" direction="in"> + <tp:docstring> </tp:docstring> </arg> </method> <method name="startVideoPreview" tp:name-for-bindings="startVideoPreview"> - <arg type="i" name="width" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - <arg type="i" name="height" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - <arg type="s" name="format" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - <arg type="i" name="shmId" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - <arg type="i" name="semId" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - <arg type="i" name="videoBufferSize" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> + <arg type="i" name="width" direction="in"> + <tp:docstring> + </tp:docstring> + </arg> + <arg type="i" name="height" direction="in"> + <tp:docstring> + </tp:docstring> + </arg> + <arg type="s" name="format" direction="in"> + <tp:docstring> + </tp:docstring> + </arg> + <arg type="i" name="shmKey" direction="out"> + <tp:docstring> + </tp:docstring> + </arg> + <arg type="i" name="semKey" direction="out"> + <tp:docstring> + </tp:docstring> + </arg> + <arg type="i" name="videoBufferSize" direction="out"> + <tp:docstring> + </tp:docstring> + </arg> </method> <method name="stopVideoPreview" tp:name-for-bindings="stopVideoPreview"> diff --git a/sflphone-client-gnome/src/dbus/dbus.c b/sflphone-client-gnome/src/dbus/dbus.c index 4f20760597cce03ae8b288a1436288d2fc20314b..d49fb4164032242a0db0987532d9b7e9b092a216 100644 --- a/sflphone-client-gnome/src/dbus/dbus.c +++ b/sflphone-client-gnome/src/dbus/dbus.c @@ -59,6 +59,72 @@ DBusGProxy * callManagerProxy; DBusGProxy * configurationManagerProxy; DBusGProxy * instanceProxy; +static void +new_call_created_cb (DBusGProxy *, const gchar *, const gchar *, const gchar *, void *); + +static void +incoming_call_cb (DBusGProxy *, const gchar *, const gchar *, const gchar *, void *); + +static void +zrtp_negotiation_failed_cb (DBusGProxy *, const gchar *, const gchar *, const gchar *, void *); + +static void +current_selected_audio_codec (DBusGProxy *, const gchar *, const gchar *, void *); + +static void +volume_changed_cb (DBusGProxy *, const gchar *, const gdouble, void *); + +static void +voice_mail_cb (DBusGProxy *, const gchar *, const guint, void *); + +static void +incoming_message_cb (DBusGProxy *, const gchar *, const gchar *, const gchar *, void *); + +static void +call_state_cb (DBusGProxy *, const gchar *, const gchar *, void *); + +static void +conference_changed_cb (DBusGProxy *, const gchar *, const gchar *, void *); + +static void +conference_created_cb (DBusGProxy *, const gchar *, void *); + +static void +conference_removed_cb (DBusGProxy *, const gchar *, void *); + +static void +record_playback_filepath_cb (DBusGProxy *, const gchar *, const gchar *); + +static void +record_playback_stoped_cb (DBusGProxy *, const gchar *); + +static void +accounts_changed_cb (DBusGProxy *, void *); + +static void +transfer_succeded_cb (DBusGProxy *, void *); + +static void +transfer_failed_cb (DBusGProxy *, void *); + +static void +secure_sdes_on_cb (DBusGProxy *, const gchar *, void *); + +static void +secure_sdes_off_cb (DBusGProxy *, const gchar *, void *); + +static void +secure_zrtp_on_cb (DBusGProxy *, const gchar *, const gchar *, void *); + +static void +secure_zrtp_off_cb (DBusGProxy *, const gchar *, void *); + +static void +show_zrtp_sas_cb (DBusGProxy *, const gchar *, const gchar *, const gboolean, void *); + +static void +confirm_go_clear_cb (DBusGProxy *, const gchar *, void *); + static void new_call_created_cb (DBusGProxy *proxy UNUSED, const gchar *accountID, const gchar *callID, const gchar *to, void *foo UNUSED) @@ -342,7 +408,7 @@ conference_created_cb (DBusGProxy *proxy UNUSED, const gchar* confID, void * foo DEBUG ("DBUS: Conference %s added", confID); conference_obj_t *new_conf; - callable_obj_t *call, *history_entry; + callable_obj_t *call; gchar* call_id; gchar** participants; gchar** part; @@ -359,12 +425,14 @@ conference_created_cb (DBusGProxy *proxy UNUSED, const gchar* confID, void * foo call_id = (gchar*) (*part); call = calllist_get_call (current_calls, call_id); + // set when this call have been added to the conference + set_timestamp(&call->_time_added); + // if a text widget is already created, disable it, use conference widget instead if (call->_im_widget) { im_widget_update_state (IM_WIDGET (call->_im_widget), FALSE); } - // if one of these participant is currently recording, the whole conference will be recorded if(call->_state == CALL_STATE_RECORD) { new_conf->_state = CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD; @@ -422,6 +490,84 @@ conference_removed_cb (DBusGProxy *proxy UNUSED, const gchar* confID, void * foo conferencelist_remove (current_calls, c->_confID); } +static void +record_playback_filepath_cb (DBusGProxy *proxy UNUSED, const gchar *id, const gchar *filepath) +{ + callable_obj_t *call = NULL; + conference_obj_t *conf = NULL; + + DEBUG("DBUS: Filepath for %s: %s", id, filepath); + + call = calllist_get_call(current_calls, id); + conf = conferencelist_get(current_calls, id); + + if(call && conf) { + ERROR("DBUS: Two object for this callid"); + return; + } + + if(!call && !conf) { + ERROR("DBUS: Could not get object"); + return; + } + + if(call) { + if(call->_recordfile == NULL) + call->_recordfile = g_strdup(filepath); + } + else if(conf) { + if(conf->_recordfile == NULL) + conf->_recordfile = g_strdup(filepath); + } +} + +static void +record_playback_stoped_cb (DBusGProxy *proxy UNUSED, const gchar *filepath) +{ + QueueElement *element; + callable_obj_t *call = NULL; + conference_obj_t *conf = NULL; + gint calllist_size, conflist_size; + gchar *recfile; + gint i; + + DEBUG("DBUS: Playback stoped for %s", filepath); + + calllist_size = calllist_get_size(history); + conflist_size = conferencelist_get_size(history); + + for(i = 0; i < calllist_size; i++) { + recfile = NULL; + element = calllist_get_nth(history, i); + if(element == NULL) { + ERROR("DBUS: ERROR: Could not find %dth call", i); + break; + } + + if(element->type == HIST_CALL) { + call = element->elem.call; + recfile = call->_recordfile; + if(recfile && (g_strcmp0(recfile, filepath) == 0)) { + call->_record_is_playing = FALSE; + } + } + } + + for(i = 0; i < conflist_size; i++) { + conf = conferencelist_get(history, i); + if(conf == NULL) { + ERROR("DBUS: ERROR: Could not find %dth conf", i); + break; + } + + recfile = conf->_recordfile; + if(recfile && (g_strcmp0(recfile, filepath) == 0)) + conf->_record_is_playing = FALSE; + } + + update_actions(); +} + static void accounts_changed_cb (DBusGProxy *proxy UNUSED, void * foo UNUSED) { @@ -680,6 +826,15 @@ dbus_connect (GError **error) dbus_g_proxy_connect_signal (callManagerProxy, "conferenceRemoved", G_CALLBACK (conference_removed_cb), NULL, NULL); + /* Playback related signals */ + dbus_g_proxy_add_signal (callManagerProxy, "recordPlaybackFilepath", G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (callManagerProxy, "recordPlaybackFilepath", + G_CALLBACK (record_playback_filepath_cb), NULL, NULL); + dbus_g_proxy_add_signal (callManagerProxy, "recordPlaybackStoped", G_TYPE_STRING, G_TYPE_INVALID); + dbus_g_proxy_connect_signal(callManagerProxy, "recordPlaybackStoped", + G_CALLBACK (record_playback_stoped_cb), NULL, NULL); + /* Security related callbacks */ dbus_g_proxy_add_signal (callManagerProxy, "secureSdesOn", G_TYPE_STRING, @@ -832,6 +987,39 @@ dbus_unhold_conference (const conference_obj_t * c) } } +gboolean +dbus_start_recorded_file_playback(const gchar *filepath) +{ + DEBUG("DBUS: Start recorded file playback %s", filepath); + + GError *error = NULL; + gboolean result; + + org_sflphone_SFLphone_CallManager_start_recorded_file_playback(callManagerProxy, + filepath, &result, &error); + + if(error) { + ERROR("Failed to call recorded file playback: %s", error->message); + g_error_free(error); + } + + return result; +} + +void +dbus_stop_recorded_file_playback(const gchar *filepath) +{ + DEBUG("DBUS: Stop recorded file playback %s", filepath); + GError *error = NULL; + org_sflphone_SFLphone_CallManager_stop_recorded_file_playback(callManagerProxy, + filepath, &error); + + if(error) { + ERROR("Failed to call stop recorded file playback: %s", error->message); + g_error_free(error); + } +} + void dbus_hang_up (const callable_obj_t * c) { @@ -2491,7 +2679,7 @@ dbus_set_accounts_order (const gchar* order) } } -gchar ** +const gchar ** dbus_get_history (void) { GError *error = NULL; diff --git a/sflphone-client-gnome/src/dbus/dbus.h b/sflphone-client-gnome/src/dbus/dbus.h index 160518cb1611dda8850da74a33f16491178675a5..a2938ff20359515947f38b129abc586d81f50c87 100644 --- a/sflphone-client-gnome/src/dbus/dbus.h +++ b/sflphone-client-gnome/src/dbus/dbus.h @@ -582,7 +582,7 @@ void dbus_set_accounts_order (const gchar* order); * Get a list of serialized hisotry entries * @return The list of history entries */ -gchar **dbus_get_history (void); +const gchar **dbus_get_history (void); /** * Set the history entries into the daemon. The daemon then write teh content @@ -649,6 +649,9 @@ dbus_detach_participant (const gchar* callID); void dbus_join_participant (const gchar* sel_callID, const gchar* drag_callID); +void +dbus_create_conf_from_participant_list(const gchar **list); + void dbus_join_conference (const gchar* sel_confID, const gchar* drag_confID); @@ -663,4 +666,17 @@ void dbus_start_video_preview (); void dbus_stop_video_preview (); +/** + * Start playback of a recorded + * @param The recorded file to start playback with + */ +gboolean dbus_start_recorded_file_playback(const gchar *); + +/** + * Stop playback of a recorded filie + * @param The recorded file to pause + */ +void dbus_stop_recorded_file_playback(const gchar *); + + #endif diff --git a/sflphone-client-gnome/src/ui.xml b/sflphone-client-gnome/src/ui.xml index 9d61626d0ae7dc97605e1b2337be30e39db77bb7..170665086346f4dfd52a6c6f781ceda0229662cb 100644 --- a/sflphone-client-gnome/src/ui.xml +++ b/sflphone-client-gnome/src/ui.xml @@ -54,6 +54,8 @@ <separator/> <toolitem name="VoicemailToolbar" action="Voicemail"/> <toolitem name="HistoryToolbar" action="History"/> + <toolitem name="StartPlaybackRecordToolbar" action="StartPlaybackRecord"/> + <toolitem name="StopPlaybackRecordToolbar" action="StopPlaybackRecord" /> </toolbar> <popup name="PopupMenu"> diff --git a/sflphone-client-gnome/src/uimanager.c b/sflphone-client-gnome/src/uimanager.c index 9f7a508f0d9ee81e70b8985c4521e92963499187..1ef277a1cadf87035fec33e510a8fbe6abec52e8 100644 --- a/sflphone-client-gnome/src/uimanager.c +++ b/sflphone-client-gnome/src/uimanager.c @@ -78,6 +78,10 @@ static GtkAction * voicemailAction; static GtkWidget * voicemailToolbar; static GtkWidget * imToolbar; static GtkAction * imAction; +static GtkWidget * playRecordWidget; +static GtkAction * playRecordAction; +static GtkWidget * stopRecordWidget; +static GtkAction * stopRecordAction; static GtkWidget * editable_num; static GtkDialog * edit_dialog; @@ -97,8 +101,7 @@ update_actions() { DEBUG ("UIManager: Update action"); - - + gtk_action_set_sensitive (GTK_ACTION (newCallAction), TRUE); gtk_action_set_sensitive (GTK_ACTION (pickUpAction), FALSE); gtk_action_set_sensitive (GTK_ACTION (hangUpAction), FALSE); @@ -176,6 +179,10 @@ update_actions() gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (newCallWidget), 0); + if(is_inserted(GTK_WIDGET (playRecordWidget), GTK_WIDGET(toolbar))) + gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(playRecordWidget)); + if(is_inserted(GTK_WIDGET (stopRecordWidget), GTK_WIDGET(toolbar))) + gtk_container_remove(GTK_CONTAINER(toolbar), GTK_WIDGET(stopRecordWidget)); if (eel_gconf_get_integer (HISTORY_ENABLED)) { gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (historyButton), -1); @@ -262,15 +269,25 @@ update_actions() if (active_calltree == current_calls) gtk_action_set_sensitive (GTK_ACTION (hangUpAction), TRUE); + if (active_calltree == history) { + gtk_action_set_sensitive (GTK_ACTION(playRecordAction), TRUE); + gtk_action_set_sensitive (GTK_ACTION(stopRecordAction), TRUE); + } - //gtk_action_set_sensitive( GTK_ACTION(newCallMenu),TRUE); g_object_ref (newCallWidget); gtk_container_remove (GTK_CONTAINER (toolbar), GTK_WIDGET (newCallWidget)); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (pickUpWidget), 0); if (active_calltree == current_calls) gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), 1); - + else if(active_calltree == history) { + if(selectedCall->_recordfile && (g_strcmp0(selectedCall->_recordfile, "") != 0)) { + if(selectedCall->_record_is_playing) + gtk_toolbar_insert(GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM(stopRecordWidget), 3); + else + gtk_toolbar_insert(GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM(playRecordWidget), 3); + } + } break; case CALL_STATE_CURRENT: DEBUG ("UIManager: Call State Current"); @@ -367,6 +384,15 @@ update_actions() gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (imToolbar), 4); } } + else if(active_calltree == history) { + if(selectedConf->_recordfile && (g_strcmp0(selectedConf->_recordfile, "") != 0)) { + if(selectedConf->_record_is_playing) + gtk_toolbar_insert(GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM(stopRecordWidget), 3); + else + gtk_toolbar_insert(GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM(playRecordWidget), 3); + } + + } break; case CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD: case CONFERENCE_STATE_ACTIVE_DETACHED_RECORD: @@ -703,6 +729,63 @@ call_record (void) sflphone_rec_call(); } +static void +start_playback_record_cb(void) +{ + gboolean result; + + DEBUG("UIManager: Start playback button pressed"); + + callable_obj_t *selectedCall = calltab_get_selected_call (history); + conference_obj_t *selectedConf = calltab_get_selected_conf (history); + + if((selectedCall == NULL) && (selectedConf == NULL)) { + ERROR("UIManager: Error: No selected object in playback record callback"); + return; + } + + if(selectedCall) { + result = dbus_start_recorded_file_playback(selectedCall->_recordfile); + selectedCall->_record_is_playing = result; + } + else if(selectedConf) { + result = dbus_start_recorded_file_playback(selectedConf->_recordfile); + selectedConf->_record_is_playing = result; + } + + update_actions(); +} + +static void +stop_playback_record_cb(void) +{ + DEBUG("UIManager: Stop playback button pressed"); + + callable_obj_t *selectedCall = calltab_get_selected_call (history); + conference_obj_t *selectedConf = calltab_get_selected_conf(history); + + if(selectedCall && selectedConf) { + ERROR("UIManager: Error: Two selected object in history treeview"); + return; + } + + if((selectedCall == NULL) && (selectedConf == NULL)) { + ERROR("UIManager: Error: No selected object in history treeview"); + return; + } + + if(selectedCall) { + dbus_stop_recorded_file_playback(selectedCall->_recordfile); + selectedCall->_record_is_playing = FALSE; + } + else if(selectedConf) { + dbus_stop_recorded_file_playback(selectedConf->_recordfile); + selectedConf->_record_is_playing = FALSE; + } + + update_actions(); +} + static void call_configuration_assistant (void * foo UNUSED) { @@ -970,6 +1053,10 @@ static const GtkActionEntry menu_entries[] = { N_ ("Minimize to system tray"), G_CALLBACK (call_minimize) }, { "Quit", GTK_STOCK_CLOSE, N_ ("_Quit"), "<control>Q", N_ ("Quit the program"), G_CALLBACK (call_quit) }, + { "StartPlaybackRecord", GTK_STOCK_MEDIA_PLAY, N_ ("_Playback record"), NULL, + N_ ("Playback recorded file"), G_CALLBACK (start_playback_record_cb) }, + { "StopPlaybackRecord", GTK_STOCK_MEDIA_PAUSE, N_ ("_Stop playback"), NULL, + N_ ("Stop recorded file playback"), G_CALLBACK (stop_playback_record_cb) }, // Edit Menu { "Edit", NULL, N_ ("_Edit"), NULL, NULL, NULL }, @@ -1137,8 +1224,7 @@ show_popup_menu (GtkWidget *my_widget, GdkEventButton *event) // TODO update the selection to make sure the call under the mouse is the call selected // call type boolean - gboolean pickup = FALSE, hangup = FALSE, hold = FALSE, copy = FALSE, - record = FALSE, im = FALSE; + gboolean pickup = FALSE, hangup = FALSE, hold = FALSE, copy = FALSE, record = FALSE, im = FALSE; gboolean accounts = FALSE; // conference type boolean @@ -1720,6 +1806,14 @@ create_toolbar_actions (GtkUIManager *ui_manager, GtkWidget **widget) "/ToolbarActions/InstantMessagingToolbar"); historyButton = gtk_ui_manager_get_widget (ui_manager, "/ToolbarActions/HistoryToolbar"); + playRecordWidget = gtk_ui_manager_get_widget(ui_manager, + "/ToolbarActions/StartPlaybackRecordToolbar"); + playRecordAction = gtk_ui_manager_get_action(ui_manager, + "/ToolbarActions/StartPlaybackRecord"); + stopRecordWidget = gtk_ui_manager_get_widget(ui_manager, + "/ToolbarActions/StopPlaybackRecordToolbar"); + stopRecordAction = gtk_ui_manager_get_action(ui_manager, + "/ToolbarActions/StopPlaybackRecord"); if(abookfactory_is_addressbook_loaded()) { contactButton = gtk_ui_manager_get_widget (ui_manager, "/ToolbarActions/AddressbookToolbar"); } diff --git a/sflphone-common/src/audio/audiorecord.cpp b/sflphone-common/src/audio/audiorecord.cpp index 52cc81b9d894ae6500f37b8553b55bded0b8c530..94c35c5954ce4514758c958b08766e1e2ab3812e 100644 --- a/sflphone-common/src/audio/audiorecord.cpp +++ b/sflphone-common/src/audio/audiorecord.cpp @@ -133,6 +133,11 @@ void AudioRecord::initFileName (std::string peerNumber) savePath_.append (fName); } +std::string AudioRecord::getFileName() +{ + return savePath_; +} + bool AudioRecord::openFile() { diff --git a/sflphone-common/src/audio/audiorecord.h b/sflphone-common/src/audio/audiorecord.h index 8432130c6008eaf887182c4cfb06a85fbe51e456..2a615b4ce3247db74a3990fc74d39d8551d8db29 100644 --- a/sflphone-common/src/audio/audiorecord.h +++ b/sflphone-common/src/audio/audiorecord.h @@ -47,14 +47,31 @@ class AudioRecord ~AudioRecord(); + /** + * Set the sampling rate for this recorder + */ void setSndSamplingRate (int smplRate); + /** + * Get the recrding sampling rate + */ int getSndSamplingRate(void) const; + /** + * Set the recording option + */ void setRecordingOption (FILE_TYPE type, SOUND_FORMAT format, int sndSmplRate, std::string path); + /** + * Init recording file path + */ void initFileName (std::string peerNumber); + /** + * Return the filepath of the recording + */ + std::string getFileName(void); + /** * Check if no otehr file is opened, then create a new one * @param fileName A string containing teh file (with/without extension) diff --git a/sflphone-common/src/audio/codecs/audiocodecfactory.cpp b/sflphone-common/src/audio/codecs/audiocodecfactory.cpp index e751d1cab51c1576cd592a900e74ee021d8cbe15..2dc459c41f762db96482334321b302de0886d608 100644 --- a/sflphone-common/src/audio/codecs/audiocodecfactory.cpp +++ b/sflphone-common/src/audio/codecs/audiocodecfactory.cpp @@ -192,9 +192,13 @@ std::vector<sfl::Codec*> AudioCodecFactory::scanCodecDirectory (void) std::string libDir = std::string (CODECS_DIR).append ("/"); std::string homeDir = std::string (HOMEDIR) + DIR_SEPARATOR_STR + "." + PROGDIR + "/"; + // look for a CODECS_PATH environment variable...used in tests + const char *envDir = getenv("CODECS_PATH"); std::vector<std::string> dirToScan; dirToScan.push_back (homeDir); dirToScan.push_back (libDir); + if (envDir) + dirToScan.push_back(std::string(envDir) + DIR_SEPARATOR_STR); for (i = 0 ; (unsigned int) i < dirToScan.size() ; i++) { std::string dirStr = dirToScan[i]; diff --git a/sflphone-common/src/audio/recordable.cpp b/sflphone-common/src/audio/recordable.cpp index 542b7c72345e1d00481114b077b3790f1c12b77e..c1be5447d54960e4da27cbbd1041ec8c622abe93 100644 --- a/sflphone-common/src/audio/recordable.cpp +++ b/sflphone-common/src/audio/recordable.cpp @@ -53,12 +53,14 @@ void Recordable::initRecFileName (std::string filename) recAudio.initFileName (filename); } +std::string Recordable::getFileName() +{ + return recAudio.getFileName(); +} void Recordable::setRecordingSmplRate (int smplRate) { - recAudio.setSndSamplingRate (smplRate); - } int Recordable::getRecordingSmplRate() const diff --git a/sflphone-common/src/audio/recordable.h b/sflphone-common/src/audio/recordable.h index e7dc6e19f30541751c9a6f51b05b99e38cc1d4b8..a5534086c9ff2b907a1e68d6cccfcd4d7e80cdeb 100644 --- a/sflphone-common/src/audio/recordable.h +++ b/sflphone-common/src/audio/recordable.h @@ -58,7 +58,7 @@ class Recordable /** * Stop recording */ - void stopRecording() { + void stopRecording(void) { recAudio.stopRecording(); } @@ -67,19 +67,27 @@ class Recordable */ void initRecFileName (std::string filename); + /** + * Return the file path for this recording + */ + std::string getFileName(void); + /** * Set recording sampling rate. */ void setRecordingSmplRate (int smplRate); + /** + * Return the recording sampling rate + */ int getRecordingSmplRate(void) const; + /** + * Virtual method to be implemented in order to the main + * buffer to retreive the recorded id. + */ virtual std::string getRecFileId() = 0; - // virtual std::string getFileName() = 0; - - // std::string getFileName() { return _filename; } - /** * An instance of audio recorder */ diff --git a/sflphone-common/src/audio/sound/audiofile.cpp b/sflphone-common/src/audio/sound/audiofile.cpp index b847d6bd2226033f5aeecce25f31cc7534ff7b33..83b3a0bc7f02cb666fa67e97c243331695d98415 100644 --- a/sflphone-common/src/audio/sound/audiofile.cpp +++ b/sflphone-common/src/audio/sound/audiofile.cpp @@ -1,5 +1,7 @@ /* - * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc. + + if(_dbus) + _dbus * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc. * Author: Yan Morin <yan.morin@savoirfairelinux.com> * * Inspired by tonegenerator of @@ -44,7 +46,7 @@ #include "manager.h" -RawFile::RawFile() : filename(), audioCodec (NULL) +RawFile::RawFile() : audioCodec (NULL) { AudioFile::_start = false; } @@ -63,20 +65,20 @@ void RawFile::loadFile (const std::string& name, sfl::AudioCodec* codec, unsigne // if the filename was already load, with the same samplerate // we do nothing - if ((filename == name) && (_sampleRate == (int)sampleRate)) { + if ((filepath == name) && (_sampleRate == (int)sampleRate)) { return; } - filename = name; + filepath = name; // no filename to load - if (filename.empty()) { + if (filepath.empty()) { throw AudioFileException("Unable to open audio file: filename is empty"); } std::fstream file; - file.open (filename.c_str(), std::fstream::in); + file.open (filepath.c_str(), std::fstream::in); if (!file.is_open()) { throw AudioFileException("Unable to open audio file"); } @@ -236,9 +238,11 @@ bool WaveFile::isFileOpened() void WaveFile::openExistingWaveFile (const std::string& fileName, int audioSamplingRate) throw(AudioFileException) { - int maxIteration = 0; + int maxIteration = 0; _debug ("WaveFile: Opening %s", fileName.c_str()); + filepath = fileName; + fileStream.open (fileName.c_str(), std::ios::in | std::ios::binary); char riff[4] = {}; @@ -437,12 +441,12 @@ void WaveFile::openExistingWaveFile (const std::string& fileName, int audioSampl } -void WaveFile::loadFile (const std::string& filename, sfl::AudioCodec * /*codec*/, unsigned int sampleRate) throw(AudioFileException) +void WaveFile::loadFile (const std::string& name, sfl::AudioCodec * /*codec*/, unsigned int sampleRate) throw(AudioFileException) { - _debug("WaveFile: Load new file %s", filename.c_str()); + _debug("WaveFile: Load new file %s", name.c_str()); try { - openFile (filename, sampleRate); + openFile (name, sampleRate); } catch(AudioFileException &e) { throw; diff --git a/sflphone-common/src/audio/sound/audiofile.h b/sflphone-common/src/audio/sound/audiofile.h index 975bfe136fbf9f5c10c815a52a0b77f415e36ec1..f6d09adf3c6646def7081f4f580018537d7bf9dd 100644 --- a/sflphone-common/src/audio/sound/audiofile.h +++ b/sflphone-common/src/audio/sound/audiofile.h @@ -76,7 +76,11 @@ public: * @param sampleRate The sample rate to read it * @return bool True on success */ - virtual void loadFile (const std::string& filename, sfl::AudioCodec *codec , unsigned int sampleRate) throw(AudioFileException) = 0; + virtual void loadFile (const std::string &, sfl::AudioCodec *, unsigned int) throw(AudioFileException) = 0; + + std::string getFilePath(void) { + return filepath; + } /** * Start the sound file @@ -105,6 +109,10 @@ protected: /** start or not */ bool _start; + + /** The absolute path to the sound file */ + std::string filepath; + }; @@ -144,9 +152,6 @@ class RawFile : public AudioFile // Assignment Operator RawFile& operator= (const RawFile& rh); - /** The absolute path to the sound file */ - std::string filename; - /** Your preferred codec */ sfl::AudioCodec* audioCodec; }; @@ -177,7 +182,7 @@ class WaveFile : public AudioFile /** * Test if the specified file already exist */ - bool isFileExist (const std::string& fileName); + bool isFileExist (const std::string&); /** * Test if file opend @@ -191,7 +196,7 @@ class WaveFile : public AudioFile * @param sampleRate The sample rate to read it * @return bool True on success */ - virtual void loadFile (const std::string& filename, sfl::AudioCodec *codec , unsigned int sampleRate) throw(AudioFileException); + virtual void loadFile (const std::string&, sfl::AudioCodec *, unsigned int) throw(AudioFileException); private: @@ -247,11 +252,6 @@ class WaveFile : public AudioFile */ std::fstream fileStream; - /** - * File name - */ - std::string fileName; - }; #endif diff --git a/sflphone-common/src/dbus/callmanager-introspec.xml b/sflphone-common/src/dbus/callmanager-introspec.xml index 61ecf9a9c04677e304c316d9a986e62e9e317d1d..5c6591855eca01beeabf2f71dbc62aef93ef759c 100644 --- a/sflphone-common/src/dbus/callmanager-introspec.xml +++ b/sflphone-common/src/dbus/callmanager-introspec.xml @@ -340,6 +340,21 @@ </arg> </method> + <signal name="recordPlaybackFilepath" tp:name-for-bindings="recordPlaybackFilepath"> + <tp:docstring> + Once after starting recording for the first time, this signal is emited to + provide the recorded file path to client application. + </tp:docstring> + <arg type="s" name="callID" /> + <arg type="s" name="filepath"/> + </signal> + + <signal name="recordPlaybackStoped" tp:name-for-bindings="recordPlaybackStoped"> + <tp:docstring/> + <arg type="s" name="filepath" /> + </signal> + + <method name="getCallDetails" tp:name-for-bindings="getCallDetails"> <tp:docstring> Get all the details about a specific call. @@ -590,6 +605,20 @@ </tp:docstring> </arg> </method> + + <method name="startRecordedFilePlayback" tp:name-for-bindings="startRecordedFilePlayback"> + <tp:added version="0.9.14"/> + <tp:docstring> + </tp:docstring> + <arg type="s" name="filepath" direction="in"/> + <arg type="b" name="result" direction="out"/> + </method> + + <method name="stopRecordedFilePlayback" tp:name-for-bindings="stopRecordedFilePlayback"> + <tp:added version="0.9.14"/> + <tp:docstring/> + <arg type="s" name="filepath" direction="in"/> + </method> <signal name="sipCallStateChanged" tp:name-for-bindings="sipCallStateChanged"> <tp:docstring> diff --git a/sflphone-common/src/dbus/callmanager.cpp b/sflphone-common/src/dbus/callmanager.cpp index 2d6beaa152f843a27d76694fd9cc9fb1b8058b15..aaafcf6f2985ab0f4f688fd29cb0e6bc8420e041 100644 --- a/sflphone-common/src/dbus/callmanager.cpp +++ b/sflphone-common/src/dbus/callmanager.cpp @@ -283,6 +283,18 @@ CallManager::getParticipantList (const std::string& confID) return Manager::instance().getParticipantList (confID); } +bool +CallManager::startRecordedFilePlayback(const std::string& filepath) +{ + return Manager::instance().startRecordedFilePlayback(filepath); +} + +void +CallManager::stopRecordedFilePlayback(const std::string& filepath) +{ + Manager::instance().stopRecordedFilePlayback(filepath); +} + void CallManager::setRecording (const std::string& callID) { diff --git a/sflphone-common/src/dbus/callmanager.h b/sflphone-common/src/dbus/callmanager.h index e9ad5c79a9559f2f1b1183d610ee637cec263c00..daca254d9e97e58b6303c03e5f4914f88ff4c522 100644 --- a/sflphone-common/src/dbus/callmanager.h +++ b/sflphone-common/src/dbus/callmanager.h @@ -100,6 +100,10 @@ class CallManager std::vector< std::string > getParticipantList (const std::string& confID); std::map< std::string, std::string > getConferenceDetails (const std::string& callID); + /* File Playback methods */ + bool startRecordedFilePlayback(const std::string& filepath); + void stopRecordedFilePlayback(const std::string& filepath); + /* General audio methods */ void setVolume (const std::string& device, const double& value); double getVolume (const std::string& device); diff --git a/sflphone-common/src/dbus/configurationmanager-introspec.xml b/sflphone-common/src/dbus/configurationmanager-introspec.xml index 80e9f76711d66d7c6a780663bd8247d5c577b26a..75f05227757e9819c3174a2477b848e3e101d9a3 100755 --- a/sflphone-common/src/dbus/configurationmanager-introspec.xml +++ b/sflphone-common/src/dbus/configurationmanager-introspec.xml @@ -689,11 +689,9 @@ </method> <method name="setNoiseSuppressState" tp:name-for-bindings="setNoiseSuppressState"> - <tp:docstring> - </tp:docstring> <arg type="s" name="state" direction="in"> <tp:docstring> - </tp:docstring> + </tp:docstring> </arg> </method> diff --git a/sflphone-common/src/history/historyitem.cpp b/sflphone-common/src/history/historyitem.cpp index bf09f7361a35bdeea11d9595df90158837fb49f2..ea981f1168f1e4f545ab6f06bfba84dcc7ae1eb5 100644 --- a/sflphone-common/src/history/historyitem.cpp +++ b/sflphone-common/src/history/historyitem.cpp @@ -127,6 +127,8 @@ HistoryItem::HistoryItem (std::string serialized_form) _confID = confID; _timeAdded = timeAdded; + + _recording_file = recordFile; } HistoryItem::~HistoryItem () @@ -148,6 +150,7 @@ bool HistoryItem::save (Conf::ConfigTree **history) sectionstr = section.str(); _error("-- Unserialized type: %s", call_type.str().c_str()); + /* _error("-- Unserialized time start: %s", _timestamp_start.c_str()); _error("-- Unserialized time stop: %s", _timestamp_stop.c_str()); _error("-- Unserialized number: %s", _number.c_str()); @@ -157,6 +160,7 @@ bool HistoryItem::save (Conf::ConfigTree **history) _error("-- Unserialized record file: %s", _recording_file.c_str()); _error("-- Unserialized conference id:%s", _confID.c_str()); _error("-- Unserialized time added: %s", _timeAdded.c_str()); + */ res = ( (*history)->setConfigTreeItem (sectionstr, "type", call_type.str()) && (*history)->setConfigTreeItem (sectionstr, "timestamp_start", _timestamp_start) @@ -168,7 +172,8 @@ bool HistoryItem::save (Conf::ConfigTree **history) && (*history)->setConfigTreeItem (sectionstr, "recordfile", _recording_file) && (*history)->setConfigTreeItem (sectionstr, "confid", _confID) && (*history)->setConfigTreeItem (sectionstr, "timeadded", _timeAdded)); - + + return res; } diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp index 85c11169d89c075e4ebb0fbf3395584fad7a4ef7..9e57888c9c9a0500bfc21a05a9a864900d30977e 100644 --- a/sflphone-common/src/managerimpl.cpp +++ b/sflphone-common/src/managerimpl.cpp @@ -259,6 +259,8 @@ bool ManagerImpl::outgoingCall (const std::string& account_id, _debug ("Manager: New outgoing call %s to %s", call_id.c_str(), to.c_str()); + stopTone(); + CallID current_call_id = getCurrentCallId(); if (hookPreference.getNumberEnabled()) { @@ -1866,13 +1868,13 @@ bool ManagerImpl::incomingCall (Call* call, const AccountID& accountId) } if (!hasCurrentCall()) { - _debug ("Manager: Has no current call"); + _debug ("Manager: Has no current call start ringing"); call->setConnectionState (Call::Ringing); ringtone (accountId); } else { - _debug ("Manager: has current call"); + _debug ("Manager: has current call, beep in current audio stream"); } addWaitingCall (call->getCallId()); @@ -2362,7 +2364,7 @@ void ManagerImpl::ringtone (const AccountID& accountID) { std::string ringchoice; sfl::AudioCodec *codecForTone; - int layer, samplerate; + int samplerate; _debug ("Manager: Ringtone"); @@ -2397,8 +2399,6 @@ void ManagerImpl::ringtone (const AccountID& accountID) return; } - layer = _audiodriver->getLayerType(); - samplerate = _audiodriver->getSampleRate(); codecForTone = static_cast<sfl::AudioCodec *>(_audioCodecFactory.getFirstCodecAvailable()); @@ -2407,6 +2407,10 @@ void ManagerImpl::ringtone (const AccountID& accountID) _toneMutex.enterMutex(); if (_audiofile) { + if(_dbus) { + std::string filepath = _audiofile->getFilePath(); + _dbus->getCallManager()->recordPlaybackStoped(filepath); + } delete _audiofile; _audiofile = NULL; } @@ -3028,9 +3032,8 @@ bool ManagerImpl::getMd5CredentialHashing (void) void ManagerImpl::setRecordingCall (const CallID& id) { - - Call *call = NULL; - Conference *conf = NULL; + Call *call = NULL; + Conference *conf = NULL; Recordable* rec = NULL; if (!isConference (id)) { @@ -3051,9 +3054,15 @@ void ManagerImpl::setRecordingCall (const CallID& id) rec = static_cast<Recordable *>(conf); } - if (rec != NULL) { - rec->setRecording(); + if (rec == NULL) { + _error("Manager: Error: Could not find recordable instance %s", id.c_str()); + return; } + + rec->setRecording(); + + if(_dbus) + _dbus->getCallManager()->recordPlaybackFilepath(id, rec->getFileName()); } bool ManagerImpl::isRecording (const CallID& id) @@ -3070,6 +3079,70 @@ bool ManagerImpl::isRecording (const CallID& id) return ret; } +bool ManagerImpl::startRecordedFilePlayback(const std::string& filepath) +{ + int sampleRate; + + _debug("Manager: Start recorded file playback %s", filepath.c_str()); + + audioLayerMutexLock(); + + if(!_audiodriver) { + _error("Manager: Error: No audio layer in start recorded file playback"); + } + + sampleRate = _audiodriver->getSampleRate(); + + audioLayerMutexUnlock(); + + _toneMutex.enterMutex(); + + if(_audiofile) { + if(_dbus) { + std::string file = _audiofile->getFilePath(); + _dbus->getCallManager()->recordPlaybackStoped(file); + } + delete _audiofile; + _audiofile = NULL; + } + + try { + _audiofile = static_cast<AudioFile *>(new WaveFile()); + + _audiofile->loadFile(filepath, NULL, sampleRate); + } + catch(AudioFileException &e) { + _error("Manager: Exception: %s", e.what()); + } + + _audiofile->start(); + + _toneMutex.leaveMutex(); + + audioLayerMutexLock(); + _audiodriver->startStream(); + audioLayerMutexUnlock(); + + return true; +} + + +void ManagerImpl::stopRecordedFilePlayback(const std::string& filepath) +{ + _debug("Manager: Stop recorded file playback %s", filepath.c_str()); + + audioLayerMutexLock(); + _audiodriver->stopStream(); + audioLayerMutexUnlock(); + + _toneMutex.enterMutex(); + if(_audiofile != NULL) { + _audiofile->stop(); + delete _audiofile; + _audiofile = NULL; + } + _toneMutex.leaveMutex(); +} void ManagerImpl::setHistoryLimit (const int& days) { @@ -3227,25 +3300,21 @@ void ManagerImpl::setEchoCancelState(std::string state) int ManagerImpl::getEchoCancelTailLength(void) { - _debug("-------------------------------------- getEchoTailLength %d", audioPreference.getEchoCancelTailLength()); return audioPreference.getEchoCancelTailLength(); } void ManagerImpl::setEchoCancelTailLength(int length) { - _debug("------------------------------------- setEchoTailLength %d", length); audioPreference.setEchoCancelTailLength(length); } int ManagerImpl::getEchoCancelDelay(void) { - _debug("------------------------------------- getEchoCancelDelay %d", audioPreference.getEchoCancelDelay()); return audioPreference.getEchoCancelDelay(); } void ManagerImpl::setEchoCancelDelay(int delay) { - _debug("------------------------------------- setEchoCancelDelay %d", delay); audioPreference.setEchoCancelDelay(delay); } diff --git a/sflphone-common/src/managerimpl.h b/sflphone-common/src/managerimpl.h index ea9d231f73bbbb9596f98a7647cc2598e72d2ef0..f6b37327a86a0cd2a0f463da4749bce5ca5f9c61 100644 --- a/sflphone-common/src/managerimpl.h +++ b/sflphone-common/src/managerimpl.h @@ -815,30 +815,6 @@ class ManagerImpl */ bool getMd5CredentialHashing (void); - /** - * Tells if the user wants to display the dialpad or not - * @return int 1 if dialpad has to be displayed - * 0 otherwise - */ - // int getDialpad( void ); - - /** - * Set the dialpad visible or not - */ - // void setDialpad (bool display); - - /** - * Tells if the user wants to display the volume controls or not - * @return int 1 if the controls have to be displayed - * 0 otherwise - */ - // int getVolumeControls( void ); - - /** - * Set the volume controls ( mic and speaker ) visible or not - */ - // void setVolumeControls (bool display); - /** * Set recording on / off * Start recording @@ -851,6 +827,18 @@ class ManagerImpl */ bool isRecording (const CallID& id); + /** + * Start playback fo a recorded file if and only if audio layer is not already started. + * @param File path of the file to play + */ + bool startRecordedFilePlayback(const std::string&); + + /** + * Stop playback of recorded file + * @param File of the file to stop + */ + void stopRecordedFilePlayback(const std::string&); + /** * Set the maximum number of days to keep in the history * @param calls The number of days diff --git a/sflphone-common/src/plug-in/pluginmanager.cpp b/sflphone-common/src/plug-in/pluginmanager.cpp index 92027908a9a49eb16bc48ab1d24e73422ae87630..4789973859aeae904c9a0a3f3ba036d18dd92c83 100644 --- a/sflphone-common/src/plug-in/pluginmanager.cpp +++ b/sflphone-common/src/plug-in/pluginmanager.cpp @@ -56,6 +56,15 @@ PluginManager::~PluginManager() _instance = 0; } +namespace { +bool hasSharedExtension(const std::string &fn) +{ + size_t dot_position = fn.rfind("."); + return (dot_position != std::string::npos and + fn.substr(dot_position) == ".so"); +} +} + int PluginManager::loadPlugins (const std::string &path) { @@ -69,7 +78,10 @@ PluginManager::loadPlugins (const std::string &path) const std::string cDir = "."; /* The directory in which plugins are dropped. Default: /usr/lib/sflphone/plugins/ */ - (path == "") ? pluginDir = std::string (PLUGINS_DIR).append ("/") :pluginDir = path; + if (path.empty()) + pluginDir = std::string (PLUGINS_DIR).append("/"); + else + pluginDir = path; _debug ("Loading plugins from %s...", pluginDir.c_str()); dir = opendir (pluginDir.c_str()); @@ -80,9 +92,9 @@ PluginManager::loadPlugins (const std::string &path) while ( (dirStruct=readdir (dir))) { /* Get the name of the current item in the directory */ current = dirStruct->d_name; - /* Test if the current item is not the parent or the current directory */ + /* Test if the current item is not the parent or the current directory and that it ends with .so*/ - if (current != pDir && current != cDir) { + if (current != pDir && current != cDir and hasSharedExtension(current)) { /* Load the dynamic library */ library = loadDynamicLibrary (pluginDir + current); diff --git a/sflphone-common/test/Makefile.am b/sflphone-common/test/Makefile.am index 42741e2b361b03c89d7c8bed0c15e9935a852112..e62c988530a4f827fe03e1de6d1140924fcb1b50 100644 --- a/sflphone-common/test/Makefile.am +++ b/sflphone-common/test/Makefile.am @@ -1,5 +1,8 @@ include ../globals.mak +TESTS_ENVIRONMENT = CODECS_PATH="$(top_builddir)/src/audio/codecs" \ + FAKE_PLUGIN_DIR="$(top_builddir)/src/plug-in/test/" \ + FAKE_PLUGIN_NAME="$(top_builddir)/src/plug-in/test/libplugintest.so" check_PROGRAMS = test test_CXXFLAGS = $(CPPUNIT_CFLAGS) diff --git a/sflphone-common/test/pluginmanagertest.cpp b/sflphone-common/test/pluginmanagertest.cpp index 9182dab99a2afa91a27338fff6df4c930d4b288e..cffbf4c3bbaa7bcfe5285242b9a5fd5229f407e0 100644 --- a/sflphone-common/test/pluginmanagertest.cpp +++ b/sflphone-common/test/pluginmanagertest.cpp @@ -37,13 +37,13 @@ using std::cout; using std::endl; -#define PLUGIN_TEST_DIR "/usr/lib/sflphone/plugins/" -#define PLUGIN_TEST_DESC "mytest" -#define PLUGIN_TEST_NAME "/usr/lib/sflphone/plugins/libplugintest.so" +#define FAKE_PLUGIN_DESC "mytest" void PluginManagerTest::setUp() { + FAKE_PLUGIN_DIR = std::string(getenv("FAKE_PLUGIN_DIR")); + FAKE_PLUGIN_NAME = std::string(getenv("FAKE_PLUGIN_NAME")); // Instanciate the plugin manager singleton _pm = PluginManager::instance(); library = 0; @@ -54,14 +54,14 @@ void PluginManagerTest::testLoadDynamicLibrary() { _debug ("-------------------- PluginManagerTest::testLoadDynamicLibrary --------------------\n"); - CPPUNIT_ASSERT (_pm->loadDynamicLibrary (PLUGIN_TEST_NAME) != NULL); + CPPUNIT_ASSERT (_pm->loadDynamicLibrary (FAKE_PLUGIN_NAME) != NULL); } void PluginManagerTest::testUnloadDynamicLibrary() { _debug ("-------------------- PluginManagerTest::testUnloadDynamicLibrary --------------------\n"); - library = _pm->loadDynamicLibrary (PLUGIN_TEST_NAME); + library = _pm->loadDynamicLibrary (FAKE_PLUGIN_NAME); CPPUNIT_ASSERT (library != NULL); CPPUNIT_ASSERT (_pm->unloadDynamicLibrary (library) == 0); } @@ -70,7 +70,7 @@ void PluginManagerTest::testInstanciatePlugin() { _debug ("-------------------- PluginManagerTest::testInstanciatePlugin --------------------\n"); - library = _pm->loadDynamicLibrary (PLUGIN_TEST_NAME); + library = _pm->loadDynamicLibrary (FAKE_PLUGIN_NAME); CPPUNIT_ASSERT (library != NULL); CPPUNIT_ASSERT (_pm->instanciatePlugin (library, &plugin) == 0); CPPUNIT_ASSERT (plugin!=NULL); @@ -80,32 +80,31 @@ void PluginManagerTest::testInitPlugin() { _debug ("-------------------- PluginManagerTest::testInitPlugin --------------------\n"); - library = _pm->loadDynamicLibrary (PLUGIN_TEST_NAME); + library = _pm->loadDynamicLibrary (FAKE_PLUGIN_NAME); CPPUNIT_ASSERT (library != NULL); CPPUNIT_ASSERT (_pm->instanciatePlugin (library, &plugin) == 0); CPPUNIT_ASSERT (plugin!=NULL); - CPPUNIT_ASSERT (plugin->getPluginName() == PLUGIN_TEST_DESC); + CPPUNIT_ASSERT (plugin->getPluginName() == FAKE_PLUGIN_DESC); } void PluginManagerTest::testRegisterPlugin() { _debug ("-------------------- PluginManagerTest::testRegisterPlugin --------------------\n"); - library = _pm->loadDynamicLibrary (PLUGIN_TEST_NAME); + library = _pm->loadDynamicLibrary (FAKE_PLUGIN_NAME); CPPUNIT_ASSERT (library != NULL); CPPUNIT_ASSERT (_pm->instanciatePlugin (library, &plugin) == 0); - CPPUNIT_ASSERT (_pm->isPluginLoaded (PLUGIN_TEST_DESC) == false); + CPPUNIT_ASSERT (_pm->isPluginLoaded (FAKE_PLUGIN_DESC) == false); CPPUNIT_ASSERT (_pm->registerPlugin (plugin, library) == 0); - CPPUNIT_ASSERT (_pm->isPluginLoaded (PLUGIN_TEST_DESC) == true); + CPPUNIT_ASSERT (_pm->isPluginLoaded (FAKE_PLUGIN_DESC) == true); } void PluginManagerTest::testLoadPlugins () { _debug ("-------------------- PluginManagerTest::testLoadPlugins --------------------\n"); try { - - CPPUNIT_ASSERT (_pm->loadPlugins (PLUGIN_TEST_DIR) == 0); - CPPUNIT_ASSERT (_pm->isPluginLoaded (PLUGIN_TEST_DESC) == true); + CPPUNIT_ASSERT (_pm->loadPlugins (FAKE_PLUGIN_DIR) == 0); + CPPUNIT_ASSERT (_pm->isPluginLoaded (FAKE_PLUGIN_DESC) == true); } catch (LibraryManagerException &e){ @@ -118,10 +117,10 @@ void PluginManagerTest::testUnloadPlugins () try { - CPPUNIT_ASSERT (_pm->loadPlugins (PLUGIN_TEST_DIR) == 0); - CPPUNIT_ASSERT (_pm->isPluginLoaded (PLUGIN_TEST_DESC) == true); + CPPUNIT_ASSERT (_pm->loadPlugins (FAKE_PLUGIN_DIR) == 0); + CPPUNIT_ASSERT (_pm->isPluginLoaded (FAKE_PLUGIN_DESC) == true); CPPUNIT_ASSERT (_pm->unloadPlugins () == 0); - CPPUNIT_ASSERT (_pm->isPluginLoaded (PLUGIN_TEST_DESC) == false); + CPPUNIT_ASSERT (_pm->isPluginLoaded (FAKE_PLUGIN_DESC) == false); } catch (LibraryManagerException &e) { diff --git a/sflphone-common/test/pluginmanagertest.h b/sflphone-common/test/pluginmanagertest.h index 35da2468f7a989857d2609c6240168cda4c1d171..2a2e78bf7815452763a334dad1bed040a2ec360d 100644 --- a/sflphone-common/test/pluginmanagertest.h +++ b/sflphone-common/test/pluginmanagertest.h @@ -94,6 +94,8 @@ class PluginManagerTest : public CppUnit::TestCase { void testUnloadPlugins (); private: + std::string FAKE_PLUGIN_DIR; + std::string FAKE_PLUGIN_NAME; PluginManager *_pm; LibraryManager *library; Plugin *plugin; diff --git a/sflphone-common/test/run_tests.sh b/sflphone-common/test/run_tests.sh new file mode 100755 index 0000000000000000000000000000000000000000..a2ce661b7cb87c3b5dd5578e10c88ce90faf1f96 --- /dev/null +++ b/sflphone-common/test/run_tests.sh @@ -0,0 +1,2 @@ +#!/bin/bash +CODECS_PATH="../src/audio/codecs" FAKE_PLUGIN_DIR="../src/plug-in/test/" FAKE_PLUGIN_NAME="../src/plug-in/test/libplugintest.so" ./test --xml || exit 1