apply FSL(Flora Software License)
[apps/home/call.git] / call-engine / voice-call-sound.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.tizenopensource.org/license
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 #include "voice-call-sound.h"
19 #include "vc-core-util.h"
20 #include "vc-core-engine-types.h"
21 #include "voice-call-core.h"
22 #include "voice-call-bt.h"
23 #include "voice-call-service.h"
24 #include <vconf.h>
25 #include <vconf-keys.h>
26
27 #include <mm_message.h>
28 #include <mm_player.h>
29 #include <mm_sound.h>
30 #include <mm_sound_private.h>
31 #include <mm_types.h>
32 #include <mm_error.h>
33
34 #include <mm_session.h>
35 #include <mm_session_private.h>
36
37 #include <devman_haptic.h>
38
39 #define VOICE_CALL_SND_INVALID_SND_HANDLE                       -1      /**<Invalid Sound lib Handle*/
40 #define VOICE_CALL_SND_INVALID_PLAYER_HANDLE            0       /**<Invalid player lib Handle*/
41
42 #define VOICE_CALL_SND_VIBON_TIME_PERIOD                1500    /**< Vibration On Timer Interval */
43 #define VOICE_CALL_SND_VIBOFF_TIME_PERIOD               500             /**< Vibration Off Timer Interval  */
44 #define VOICE_CALL_SND_INCREMENT_TIMER_INTERVAL 2000    /**< Incremental Melody Timer Interval  */
45 #define VOICE_CALL_SND_VIB_THEN_MELODY_TIMER_INTERVAL   6000    /**< 6 sec  (3 * (VOICE_CALL_SND_VIBON_TIME_PERIOD + VOICE_CALL_SND_VIBOFF_TIME_PERIOD)) approximately*/
46 #define VOICE_CALL_SND_2ND_CALL_BEEP_INTERVAL   2500
47
48 #define VOICE_CALL_SND_DEFAULT_RINGTONE_PATH            MEDIADIR"/01_Minimal_tone.mp3"
49 #define VOICE_CALL_SND_SECOND_RINGTONE_PATH                     MEDIADIR"/Call_WaitingTone.wav"
50
51 #define VOICE_CALL_SND_CONNECT_SIGNAL_PATH                      MEDIADIR"/03_Call_connect.wav"
52 #define VOICE_CALL_SND_DISCONNECT_SIGNAL_PATH           MEDIADIR"/04_Call_disconnect.wav"
53 #define VOICE_CALL_SND_MINUTE_MINDER_SIGNAL_PATH                MEDIADIR"/03_Call_connect.wav"
54
55 #define VOICE_CALL_SND_USER_BUSY_SIGNAL_PATH            MEDIADIR"/Call_BusyTone.wav"
56 #define VOICE_CALL_SND_NW_CONGESTION_SIGNAL_PATH        MEDIADIR"/Call_NwCongestionTone.wav"
57 #define VOICE_CALL_SND_ERROR_SIGNAL_PATH                                MEDIADIR"/Call_ErrorTone.wav"
58
59 #ifdef VOICE_CALL_RINGTONE_ELEVATOR
60 #define VOICE_CALL_SND_INITIAL_VOL_LEVEL                        1
61 #define VOICE_CALL_SND_RING_ELEVATOR_TIME_VAL           2000    /*3 Seconds Approx. */
62 #endif
63
64 /**
65  * Enumeration for volume level of 10 levels
66  */
67 typedef enum _voicecall_snd_mm_vol_level9_t {
68         VOICE_CALL_SND_MM_VOLUME_LEVEL_0_9 = 0,                 /**< volume level 1 of 10 */
69         VOICE_CALL_SND_MM_VOLUME_LEVEL_1_9 = 16,                /**< volume level 2 of 10 */
70         VOICE_CALL_SND_MM_VOLUME_LEVEL_2_9 = 28,                /**< volume level 3 of 10 */
71         VOICE_CALL_SND_MM_VOLUME_LEVEL_3_9 = 39,                /**< volume level 4 of 10 */
72         VOICE_CALL_SND_MM_VOLUME_LEVEL_4_9 = 50,                /**< volume level 5 of 10 */
73         VOICE_CALL_SND_MM_VOLUME_LEVEL_5_9 = 62,                /**< volume level 6 of 10 */
74         VOICE_CALL_SND_MM_VOLUME_LEVEL_6_9 = 73,                /**< volume level 7 of 10 */
75         VOICE_CALL_SND_MM_VOLUME_LEVEL_7_9 = 82,                /**< volume level 8 of 10 */
76         VOICE_CALL_SND_MM_VOLUME_LEVEL_8_9 = 91,                /**< volume level 9 of 10 */
77         VOICE_CALL_SND_MM_VOLUME_LEVEL_9_9 = 100,               /**< volume level 10 of 10 */
78 } voicecall_snd_mm_vol_level9_t;
79
80 typedef struct __voicecall_snd_path_info_t {
81         int phone_path;                                 /**< normal call state path */
82         int alert_phone_path;                           /**< alert sound to other party (record alert beep or answering machine guidance) */
83         gboolean bmic_on;
84 } voicecall_snd_path_info_t;
85
86 /* Local Fucntion Declerations */
87 /**
88  * This function prepares to start the melody to be played according to the given parameters
89  *
90  * @return              Returns TRUE on success or FALSE on failure
91  * @param[in]           papp_snd                        Handle to the Sound Manager
92  * @param[in]           bis_increasing          TRUE - Increasing Melody, FALSE -Normal Melody
93  * @param[in]           call_handle             Call Handle of the Incoming Call
94  */
95 static gboolean __voicecall_snd_start_melody(voicecall_snd_mgr_t *papp_snd, gboolean bis_increasing, int call_handle);
96
97  /**
98 * This function create the mm player
99 *
100 * @return       turns TRUE on success or FALSE on failure
101 * @param[in]            papp_snd                Handle to the Soudn Manager
102 * @param[in]            pPlayer         Handle to the mm player
103 * @param[in]            play_type               Play Type of the Sound
104 */
105 static gboolean __voicecall_snd_create_player(voicecall_snd_mgr_t *papp_snd, MMHandleType * pPlayer, voicecall_snd_play_type_t play_type);
106
107  /**
108  * This function starts the vibration
109  *
110  * @return              Returns nothing
111  * @param[in]           papp_snd                        Handle to the Sound Manager
112  */
113 static void __voicecall_snd_start_vibration(voicecall_snd_mgr_t *papp_snd);
114
115 /**
116 * This function stops the vibration
117 *
118 * @return               Returns TRUE on success or FALSE on failure
119 * @param[in]            papp_snd                        Handle to the Sound Manager
120 */
121 static void __voicecall_snd_stop_vibration(voicecall_snd_mgr_t *papp_snd);
122
123 /**
124 * This function serves as the callback for vibration then melody timer
125 *
126 * @return               Returns TRUE on success or FALSE on failure
127 * @param[in]            data                    Local data set by the caller
128 */
129 static gboolean __voicecall_snd_vib_then_melody_cb(void *data);
130
131  /**
132  * This function serves as the callbback for the MM Player
133  *
134  * @return              Returns TRUE on success or FALSE on failure
135  * @param[in]           message         MM Message from the MM Player
136  * @param[in]           data                    Data send by the MM Player according to the Message
137  * @param[in]           user_data       Local Data by the Caller
138  */
139 static int __voicecall_snd_mmplayer_cb(int message, void *data, void *user_data);
140
141 static void __voicecall_snd_mmplayer_signal_cb(gpointer puser_data);
142
143  /**
144  * This function serves as the callback for the increasing melody periodic timer
145  *
146  * @return              Returns TRUE if sound cane be played or FALSE otherwise
147  * @param[in]           data            Loca Data set by the caller
148  */
149 static gboolean __voicecall_snd_increasing_melody_cb(void *data);
150
151  /**
152 * This function plays the ringtone melody according to the settings
153 *
154 * @return               void
155 * @param[in]            papp_snd                Handle to the Sound Manager
156 * @param[in]            bis_increasing          TRUE - increasing melody, FALSE - normal
157 */
158 static gboolean __voicecall_snd_play_melody(voicecall_snd_mgr_t *papp_snd, gboolean bis_increasing);
159
160 /**
161  * This function retreives the tapi sound path to be used according to the current status
162  *
163  * @return              void
164  * @param[in]           papp_snd                Handle to Sound Manager
165  * @param[out]  voice_snd_path          Tapi Sound Path
166  */
167 static void __voicecall_snd_get_voice_path(voicecall_snd_mgr_t *papp_snd, int *voice_snd_path);
168
169 #ifdef VOICE_CALL_RINGTONE_ELEVATOR
170
171 static gboolean __voicecall_and_start_ring_elevator_cb(gpointer pdata);
172 static void __voicecall_snd_start_ring_elevator(voicecall_snd_mgr_t *papp_snd);
173 static void __voicecall_snd_cancel_ring_elevator(voicecall_snd_mgr_t *papp_snd);
174 #endif
175
176 /*Function Defintions*/
177 /**
178  * This function initializes the sound functionalties required by the Application
179  *
180  * @return              Returns TRUE on success or FALSE on failure
181  * @param[in]           pcall_core              Handle to voicecall core
182  * @param[out]  papp_snd                        Handle to the Sound Manager
183  */
184 gboolean voicecall_snd_init(void *pcall_core, voicecall_snd_mgr_t **papp_snd)
185 {
186         voicecall_snd_mgr_t *psnd_mgr = NULL;
187
188         CALL_ENG_DEBUG(ENG_DEBUG, "Sound CM Test\n");
189
190         psnd_mgr = (voicecall_snd_mgr_t *)calloc(1, sizeof(voicecall_snd_mgr_t));
191
192         if (psnd_mgr == NULL) {
193                 CALL_ENG_DEBUG(ENG_ERR, "Memory Allocation Failed\n");
194                 return FALSE;
195         }
196         CALL_ENG_DEBUG(ENG_DEBUG, "psnd_mgr alloctated memory:[%d]\n", sizeof(voicecall_snd_mgr_t));
197
198         /*Store  voice call Handle */
199         psnd_mgr->pcall_core = pcall_core;
200 #ifdef _NEW_SND_
201         psnd_mgr->current_snd_path = VOICE_CALL_SND_PATH_RECEIVER;
202         psnd_mgr->old_snd_path = VOICE_CALL_SND_PATH_NONE;
203 #endif
204
205         psnd_mgr->bsound_cm_state = FALSE;
206
207         psnd_mgr->pmm_player = VOICE_CALL_SND_INVALID_PLAYER_HANDLE;
208         psnd_mgr->pmm_signal_player = VOICE_CALL_SND_INVALID_SND_HANDLE;
209
210         psnd_mgr->mmfsoundplay_handle = VOICE_CALL_SND_INVALID_SND_HANDLE;
211         psnd_mgr->mmfalternateplay_handle = VOICE_CALL_SND_INVALID_SND_HANDLE;
212
213         psnd_mgr->psignal_play_end_cb = NULL;
214         psnd_mgr->psignal_play_end_cb_data = NULL;
215
216         /*Return the created Sound Manager */
217         *papp_snd = psnd_mgr;
218         return TRUE;
219
220 }
221
222 void __voicecall_snd_alternate_sound_cb(void *puser_data);
223 void __voicecall_snd_play_alternate_sound(voicecall_snd_mgr_t *papp_snd);
224 gboolean __voicecall_snd_stop_alternate_sound(voicecall_snd_mgr_t *papp_snd);
225
226 gboolean __voicecall_snd_alternate_sound_idle_cb(void *puser_data)
227 {
228         voicecall_snd_mgr_t *papp_snd = (voicecall_snd_mgr_t *)puser_data;
229         call_vc_core_state_t *pcall_core = (call_vc_core_state_t *)papp_snd->pcall_core;
230
231         CALL_ENG_DEBUG(ENG_DEBUG, "..\n");
232
233         if (TRUE == papp_snd->balternate_play) {
234                 if ((FALSE == voicecall_core_is_connected_call_exist(pcall_core->pcall_engine))
235                     && (TRUE == voicecall_core_is_incoming_call_exists(pcall_core->pcall_engine))) {
236                         /* case : during 2nd incoming call, connected call is cleared. so, just 1 incoming call case... */
237                         CALL_ENG_DEBUG(ENG_DEBUG, "2nd incoming -> just single incoming call.\n");
238                         voicecall_snd_prepare_alert(papp_snd, papp_snd->incoming_call_handle);
239                         voicecall_snd_change_mm_path(papp_snd, VOICE_CALL_MM_RING_TONE);
240                         voicecall_snd_play_alert(papp_snd);
241                 } else {
242                         __voicecall_snd_play_alternate_sound(papp_snd);
243                 }
244         }
245
246         return FALSE;
247 }
248
249 gboolean __voicecall_snd_alternate_play_timeout_cb(gpointer pdata)
250 {
251         voicecall_snd_mgr_t *papp_snd = (voicecall_snd_mgr_t *)pdata;
252
253         CALL_ENG_DEBUG(ENG_DEBUG, "..\n");
254         if (papp_snd->balternate_play == TRUE) {
255                 __voicecall_snd_play_alternate_sound(papp_snd);
256         }
257
258         return FALSE;
259 }
260
261 void __voicecall_snd_play_alternate_sound(voicecall_snd_mgr_t *papp_snd)
262 {
263         CALL_ENG_DEBUG(ENG_DEBUG, "..\n");
264         call_vc_core_state_t *pcall_core = (call_vc_core_state_t *)papp_snd->pcall_core;
265
266         if (TRUE == voicecall_core_is_incoming_call_exists(pcall_core->pcall_engine)) {
267                 CALL_ENG_DEBUG(ENG_DEBUG, "Incoming call is there!Play Alternate Sound \n");
268
269                 int mmf_error = -1;
270
271                 char ring_tone[VOICE_CALL_SND_RINGTONE_PATH_LEN];
272                 snprintf(ring_tone, sizeof(ring_tone), "file://%s", VOICE_CALL_SND_SECOND_RINGTONE_PATH);
273
274                 voicecall_snd_change_mm_path(pcall_core->papp_snd, VOICE_CALL_MM_SECOND_CALL_TONE);
275
276                 CALL_ENG_DEBUG(ENG_DEBUG, "Call mm_sound_play_sound to play alternate ringtonen\n");
277                 mmf_error = mm_sound_play_sound(VOICE_CALL_SND_SECOND_RINGTONE_PATH, VOLUME_TYPE_CALL, __voicecall_snd_alternate_sound_cb, papp_snd, &papp_snd->mmfalternateplay_handle);
278
279                 if (MM_ERROR_NONE == mmf_error) {
280                         papp_snd->balternate_play = TRUE;
281                         papp_snd->ringtone_sound_status = VOICE_CALL_SND_STATUS_PLAY;
282                         CALL_ENG_DEBUG(ENG_DEBUG, "Alternate Sound Play Called,papp_snd->balternate_play=%d \n", papp_snd->balternate_play);
283                 } else {
284                         papp_snd->ringtone_sound_status = VOICE_CALL_SND_STATUS_STOP;
285                         papp_snd->balternate_play = FALSE;
286                         CALL_ENG_DEBUG(ENG_DEBUG, "mmf_error = [0x%x] \n", mmf_error);
287                 }
288                 CALL_ENG_DEBUG(ENG_DEBUG, "End of Alternate Sound!\n");
289         }
290 }
291
292 gboolean __voicecall_snd_stop_alternate_sound(voicecall_snd_mgr_t *papp_snd)
293 {
294         CALL_ENG_DEBUG(ENG_DEBUG, " papp_snd->balternate_play = %d\n", papp_snd->balternate_play);
295         if (TRUE == papp_snd->balternate_play) {
296                 /*Only Stop if it is in Play State */
297                 if (VOICE_CALL_SND_STATUS_PLAY == papp_snd->ringtone_sound_status) {
298                         int error = 0;
299                         error = mm_sound_stop_sound(papp_snd->mmfalternateplay_handle);
300                         papp_snd->mmfalternateplay_handle = -1;
301                         papp_snd->ringtone_sound_status = VOICE_CALL_SND_STATUS_STOP;
302                         CALL_ENG_DEBUG(ENG_ERR, "Alternate Ringtone Stopeed,Error Code: [0x%x] \n", error);
303                 }
304                 papp_snd->balternate_play = FALSE;
305                 return TRUE;
306         }
307         return FALSE;
308 }
309
310 void __voicecall_snd_alternate_sound_cb(void *puser_data)
311 {
312         voicecall_snd_mgr_t *papp_snd = (voicecall_snd_mgr_t *)puser_data;
313         call_vc_core_state_t *pcall_core = (call_vc_core_state_t *)papp_snd->pcall_core;
314
315         CALL_ENG_DEBUG(ENG_DEBUG, "papp_snd->balternate_play= %d\n", papp_snd->balternate_play);
316
317         papp_snd->ringtone_sound_status = VOICE_CALL_SND_STATUS_STOPPED;
318
319         /*If connected call exists then change the audio path */
320         if ((TRUE == voicecall_core_is_connected_call_exist(pcall_core->pcall_engine)) || (TRUE == voicecall_core_is_outgoing_call_exists(pcall_core->pcall_engine))) {
321                 voicecall_snd_change_path(papp_snd);
322         }
323
324         g_timeout_add(VOICE_CALL_SND_2ND_CALL_BEEP_INTERVAL, __voicecall_snd_alternate_sound_idle_cb, papp_snd);
325
326 }
327
328 void voicecall_snd_prepare_alert(voicecall_snd_mgr_t *papp_snd, int call_handle)
329 {
330         CALL_ENG_DEBUG(ENG_DEBUG, "..\n");
331
332         call_vc_core_state_t *pcall_core = (call_vc_core_state_t *)papp_snd->pcall_core;
333         int err_code = -1;
334
335         papp_snd->incoming_call_handle = call_handle;
336
337         if (TRUE == voicecall_core_is_connected_call_exist(pcall_core->pcall_engine)) {
338                 CALL_ENG_DEBUG(ENG_DEBUG, "Alternate Sound Needs to be played \n");
339                 papp_snd->ringtone_sound_status = VOICE_CALL_AND_STATUS_ALTERNATE_PLAY;
340                 return;
341         }
342
343         /*
344            Always stop the alert before starting another
345            to make sure the previous alert is proerly closed.
346          */
347         voicecall_snd_stop_alert(papp_snd);
348
349         /*Initizlize Variables */
350         papp_snd->pmm_player = VOICE_CALL_SND_INVALID_PLAYER_HANDLE;
351         papp_snd->settings_sound_status = FALSE;
352         papp_snd->settings_vib_status = FALSE;
353
354         err_code = vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &papp_snd->settings_sound_status);
355         CALL_ENG_DEBUG(ENG_DEBUG, "cur_sound_status = %d, error_code = %d\n", papp_snd->settings_sound_status, err_code);
356
357         err_code = vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &papp_snd->settings_vib_status);
358         CALL_ENG_DEBUG(ENG_DEBUG, "cur_vib_status = %d, error_code = %d\n", papp_snd->settings_vib_status, err_code);
359
360         if (papp_snd->settings_sound_status == FALSE)
361                 papp_snd->bmute_play = TRUE;
362
363         __voicecall_snd_start_melody(papp_snd, FALSE, call_handle);
364
365 }
366
367 void voicecall_snd_play_alert(voicecall_snd_mgr_t *papp_snd)
368 {
369         call_vc_core_state_t *pcall_core = (call_vc_core_state_t *)papp_snd->pcall_core;
370
371         CALL_ENG_DEBUG(ENG_DEBUG, "papp_snd->ringtone_sound_status=%d \n ", papp_snd->ringtone_sound_status);
372
373         if (VOICE_CALL_AND_STATUS_ALTERNATE_PLAY == papp_snd->ringtone_sound_status) {
374                 if (TRUE == voicecall_core_is_connected_call_exist(pcall_core->pcall_engine)) {
375                         CALL_ENG_DEBUG(ENG_DEBUG, "Starting Alternate Sound \n");
376                         papp_snd->balternate_play_count = 0;
377                         __voicecall_snd_play_alternate_sound(papp_snd);
378                 }
379         }
380
381         if (VOICE_CALL_SND_STATUS_READY != papp_snd->ringtone_sound_status) {
382                 CALL_ENG_DEBUG(ENG_DEBUG, " Invalid ringtone_sound_status: %d \n ", papp_snd->ringtone_sound_status);
383                 return;
384         }
385
386         papp_snd->ringtone_sound_status = VOICE_CALL_SND_STATUS_PROCESSED;
387
388         CALL_ENG_DEBUG(ENG_DEBUG, " [##### papp_snd->settings_sound_status #####] : %d \n ", papp_snd->settings_sound_status);
389         CALL_ENG_DEBUG(ENG_DEBUG, " [##### papp_snd->settings_vib_status #####] : %d \n ", papp_snd->settings_vib_status);
390
391         if (papp_snd->settings_sound_status) {
392                 __voicecall_snd_play_melody(papp_snd, FALSE);
393         } else if (papp_snd->bmute_play) {
394                 /*Change the path to the earjack headset and play the ringtone */
395                 voicecall_snd_change_mm_path(papp_snd, VOICE_CALL_MM_MUTE_PLAY);
396                 __voicecall_snd_play_melody(papp_snd, FALSE);
397         }
398         if (papp_snd->settings_vib_status) {
399                 __voicecall_snd_start_vibration(papp_snd);
400         }
401 }
402
403 #ifdef VOICE_CALL_RINGTONE_ELEVATOR
404
405 gboolean __voicecall_and_start_ring_elevator_cb(gpointer pdata)
406 {
407         voicecall_snd_mgr_t *papp_snd = (voicecall_snd_mgr_t *)pdata;
408         int volume_level = VOICE_CALL_VOL_LEVEL_1;
409         int ret_value = -1;
410
411         CALL_ENG_DEBUG(ENG_DEBUG, "..\n");
412
413         /*Get the settings current ringtone volume level and set to media player */
414         ret_value = vconf_get_int(VCONFKEY_SETAPPL_PROFILE_CURRENT_CALL_VOLUME_INT, &volume_level);
415         if (ret_value != 0) {
416                 CALL_ENG_DEBUG(ENG_ERR, "settings read failed Error: %d\n", ret_value);
417         }
418         CALL_ENG_DEBUG(ENG_DEBUG, "Settings Volume Level = %d\n", volume_level);
419
420         if (papp_snd->pmm_player != VOICE_CALL_SND_INVALID_PLAYER_HANDLE) {
421                 ret_value = mm_sound_volume_set_value(VOLUME_TYPE_RINGTONE, volume_level);
422                 if (MM_ERROR_NONE != ret_value) {
423                         CALL_ENG_DEBUG(ENG_ERR, "Set Volume Error: [0x%x]\n", ret_value);
424                 }
425         } else {
426                 CALL_ENG_DEBUG(ENG_ERR, "Invalid MM Plauer %d\n", papp_snd->pmm_player);
427         }
428
429         return FALSE;
430 }
431
432 void __voicecall_snd_start_ring_elevator(voicecall_snd_mgr_t *papp_snd)
433 {
434         CALL_ENG_DEBUG(ENG_DEBUG, "..\n");
435
436         papp_snd->ring_elvator_timerid = g_timeout_add(VOICE_CALL_SND_RING_ELEVATOR_TIME_VAL, __voicecall_and_start_ring_elevator_cb, papp_snd);
437 }
438
439 void __voicecall_snd_cancel_ring_elevator(voicecall_snd_mgr_t *papp_snd)
440 {
441         CALL_ENG_DEBUG(ENG_DEBUG, "..\n");
442         if (papp_snd->ring_elvator_timerid > 0) {
443                 g_source_remove(papp_snd->ring_elvator_timerid);
444                 papp_snd->ring_elvator_timerid = 0;
445         }
446 }
447 #endif
448
449 gboolean voicecall_snd_mute_alert(voicecall_snd_mgr_t *papp_snd)
450 {
451         CALL_ENG_DEBUG(ENG_DEBUG, "..\n");
452         if (papp_snd->pmm_player != VOICE_CALL_SND_INVALID_PLAYER_HANDLE) {
453                 int ret_value = 0;
454
455                 ret_value = mm_player_set_mute(papp_snd->pmm_player, TRUE);
456                 CALL_ENG_DEBUG(ENG_DEBUG, "MM Set Mute Error code: [0x%x] \n", ret_value);
457         }
458
459         if (TRUE == papp_snd->bvibration) {
460                 CALL_ENG_DEBUG(ENG_DEBUG, "Vibration is playing, stopping vibration \n");
461                 __voicecall_snd_stop_vibration(papp_snd);
462         }
463 #ifdef VOICE_CALL_RINGTONE_ELEVATOR
464         __voicecall_snd_cancel_ring_elevator(papp_snd);
465 #endif
466
467         /*Make Vibration than melody flag to FALSE, so melody will not be played when it is muted */
468         papp_snd->bvibration_then_melody = FALSE;
469
470         /*Make Increasing Melody flag to FALSE, so melody volume will not be increased when it is muted */
471         papp_snd->bincreasingmelody = FALSE;
472
473         return FALSE;
474 }
475
476 /**
477  * This function stops the sound alert
478  *
479  * @return              void
480  * @param[in]           papp_snd                        Handle to Sound Manager
481  */
482 void voicecall_snd_stop_alert(voicecall_snd_mgr_t *papp_snd)
483 {
484
485         CALL_ENG_DEBUG(ENG_DEBUG, "..\n");
486
487         __voicecall_snd_stop_vibration(papp_snd);
488
489         if (TRUE == __voicecall_snd_stop_alternate_sound(papp_snd)) {
490                 CALL_ENG_DEBUG(ENG_DEBUG, "Alternate sound stopped \n");
491                 return;
492         }
493 #ifdef VOICE_CALL_RINGTONE_ELEVATOR
494         /*Stop Ring Elevator */
495         __voicecall_snd_cancel_ring_elevator(papp_snd);
496 #endif
497
498         CALL_ENG_DEBUG(ENG_DEBUG, "pmm_player = %d \n", papp_snd->pmm_player);
499         if (papp_snd->pmm_player != VOICE_CALL_SND_INVALID_PLAYER_HANDLE) {
500                 int ret_value = 0;
501                 MMPlayerStateType mmplayer_state = MM_PLAYER_STATE_NONE;
502
503                 /*Sound Stop requested by the Application */
504                 papp_snd->ringtone_sound_status = VOICE_CALL_SND_STATUS_STOP;
505
506                 mm_player_get_state(papp_snd->pmm_player, &mmplayer_state);
507
508                 CALL_ENG_DEBUG(ENG_DEBUG, "Callling mmplayer_stop, current mm state = %d, Player = %d\n", mmplayer_state, papp_snd->pmm_player);
509                 if (MM_PLAYER_STATE_PLAYING == mmplayer_state || MM_PLAYER_STATE_PAUSED == mmplayer_state) {
510                         ret_value = mm_player_stop(papp_snd->pmm_player);
511                         if (MM_ERROR_NONE != ret_value) {
512                                 CALL_ENG_DEBUG(ENG_ERR, "mmplayer_stop failed: [0x%x]\n", ret_value);
513                         }
514                 }
515
516                 CALL_ENG_DEBUG(ENG_DEBUG, "Callling mmplayer_unrealize, Player = %d\n", papp_snd->pmm_player);
517                 ret_value = mm_player_unrealize(papp_snd->pmm_player);
518                 if (MM_ERROR_NONE != ret_value) {
519                         CALL_ENG_DEBUG(ENG_ERR, "mmplayer_unrealize failed: [0x%x]\n", ret_value);
520                 }
521
522                 CALL_ENG_DEBUG(ENG_DEBUG, "Callling mmplayer_destroy, Player = %d\n", papp_snd->pmm_player);
523                 ret_value = mm_player_destroy(papp_snd->pmm_player);
524                 if (MM_ERROR_NONE != ret_value) {
525                         CALL_ENG_DEBUG(ENG_ERR, "mmplayer_destroy failed: [0x%x]\n", ret_value);
526                 }
527                 papp_snd->pmm_player = VOICE_CALL_SND_INVALID_PLAYER_HANDLE;
528
529                 papp_snd->ringtone_sound_status = VOICE_CALL_SND_STATUS_STOPPED;
530         }
531
532         /* Stop All periodic Timers */
533         papp_snd->bvibration_then_melody = FALSE;
534         papp_snd->bincreasingmelody = FALSE;
535
536         /* Make the Current Sound Playing Call HAndle Invalid */
537         papp_snd->current_playing_call_handle = -1;
538
539         papp_snd->bmute_play = FALSE;
540 }
541
542 gboolean voicecall_snd_set_play_end_callback(voicecall_snd_mgr_t *papp_snd, voicecall_snd_callback psignal_play_end_cb, gpointer psignal_play_end_cb_data)
543 {
544         CALL_ENG_DEBUG(ENG_DEBUG, "signal_type = %d\n", papp_snd->signal_type);
545
546         if (VOICE_CALL_SND_STATUS_NONE == papp_snd->signal_sound_status) {
547                 CALL_ENG_DEBUG(ENG_DEBUG, "No Signal Being Played\n");
548                 return FALSE;
549         }
550
551         papp_snd->psignal_play_end_cb = psignal_play_end_cb;
552         papp_snd->psignal_play_end_cb_data = psignal_play_end_cb_data;
553
554         return TRUE;
555 }
556
557 /**
558  * This function plays call sound
559  *
560  * @return              Returns TRUE on success or FALSE on failure
561  * @param[in]           papp_snd                        Handle to Sound Manager
562  */
563 gboolean voicecall_snd_is_signal_playing(voicecall_snd_mgr_t *papp_snd)
564 {
565         CALL_ENG_DEBUG(ENG_DEBUG, "Signal Sound Status : [%d] \n", papp_snd->signal_sound_status);
566         if ((papp_snd->pmm_signal_player != VOICE_CALL_SND_INVALID_SND_HANDLE) && (VOICE_CALL_SND_STATUS_PLAY == papp_snd->signal_sound_status)) {
567                 CALL_ENG_DEBUG(ENG_DEBUG, "Signal is playing \n");
568                 return TRUE;
569         }
570
571         CALL_ENG_DEBUG(ENG_DEBUG, "Signal is not playing \n");
572         return FALSE;
573 }
574
575 gboolean voicecall_snd_play_signal(voicecall_snd_mgr_t *papp_snd, voicecall_snd_callback psignal_play_end_cb, gpointer psignal_play_end_cb_data)
576 {
577         int ret_value = 0;
578
579         CALL_ENG_DEBUG(ENG_DEBUG, "signal_type = %d\n", papp_snd->signal_type);
580
581         if (VOICE_CALL_SIGNAL_NONE == papp_snd->signal_type) {
582                 CALL_ENG_DEBUG(ENG_DEBUG, "No Signal Type Assinged\n");
583                 return FALSE;
584         }
585
586         /*
587            Always stop the signal before playing another one
588            This is to make sure that previous signal sound is stopeed completely
589          */
590         voicecall_snd_stop_signal(papp_snd);
591
592         /*Set status, the signal play is being prepared */
593         papp_snd->signal_sound_status = VOICE_CALL_SND_STATUS_READY;
594         CALL_ENG_DEBUG(ENG_DEBUG, "papp_snd->signal_sound_status = %d\n", papp_snd->signal_sound_status);
595
596         papp_snd->psignal_play_end_cb = psignal_play_end_cb;
597         papp_snd->psignal_play_end_cb_data = psignal_play_end_cb_data;
598
599         if (TRUE == voicecall_snd_is_effect_playing(papp_snd)) {
600                 CALL_ENG_DEBUG(ENG_ERR, "Stopping effect tone to play signal \n ");
601                 voicecall_snd_stop_effect_tone(papp_snd);
602         }
603
604         CALL_ENG_DEBUG(ENG_ERR, "Changing path to play signal\n ");
605         voicecall_snd_change_mm_path(papp_snd, VOICE_CALL_MM_SIGNAL_TONE);
606         CALL_ENG_DEBUG(ENG_ERR, "Changing path to play signal Over\n ");
607
608         CALL_ENG_DEBUG(ENG_DEBUG, "signal_tone = %s\n", papp_snd->signal_tone);
609         ret_value = mm_sound_play_sound(papp_snd->signal_tone, VOLUME_TYPE_CALL, __voicecall_snd_mmplayer_signal_cb, papp_snd, &papp_snd->pmm_signal_player);
610         if (MM_ERROR_NONE != ret_value) {
611                 papp_snd->signal_sound_status = VOICE_CALL_SND_STATUS_NONE;
612                 CALL_ENG_DEBUG(ENG_ERR, "mm_sound_play_sound failed,Error: [0x%x]\n", ret_value);
613         } else {
614                 CALL_ENG_DEBUG(ENG_DEBUG, "papp_snd->pmm_signal_player[%d]\n", papp_snd->pmm_signal_player);
615                 papp_snd->signal_sound_status = VOICE_CALL_SND_STATUS_PLAY;
616         }
617         CALL_ENG_DEBUG(ENG_DEBUG, "Signal Play Started, Sound Status is: %d\n", papp_snd->signal_sound_status);
618
619         return TRUE;
620 }
621
622 /**
623  * This function stops the sound alert
624  *
625  * @return              void
626  * @param[in]           papp_snd                        Handle to Sound Manager
627  */
628 void voicecall_snd_stop_signal(voicecall_snd_mgr_t *papp_snd)
629 {
630         int ret_value = 0;
631
632         CALL_ENG_DEBUG(ENG_DEBUG, "Sound Status: %d, papp_snd->pmm_signal_player(%d)\n", papp_snd->signal_sound_status, papp_snd->pmm_signal_player);
633         if (papp_snd->pmm_signal_player != VOICE_CALL_SND_INVALID_SND_HANDLE) {
634                 if (VOICE_CALL_SND_STATUS_PLAY == papp_snd->signal_sound_status) {
635                         papp_snd->signal_sound_status = VOICE_CALL_SND_STATUS_STOPPED;
636
637                         CALL_ENG_DEBUG(ENG_DEBUG, "Stopping Signal Sound \n");
638                         ret_value = mm_sound_stop_sound(papp_snd->pmm_signal_player);
639                         if (MM_ERROR_NONE != ret_value) {
640                                 CALL_ENG_DEBUG(ENG_ERR, "mm_sound_stop_sound failed: [0x%x]\n", ret_value);
641                         }
642                 } else {
643                         CALL_ENG_DEBUG(ENG_DEBUG, "Sound Play Over / Already Stopped \n");
644                 }
645                 papp_snd->pmm_signal_player = VOICE_CALL_SND_INVALID_SND_HANDLE;
646         }
647         if (papp_snd->psignal_play_end_cb != NULL) {
648                 papp_snd->psignal_play_end_cb(papp_snd->psignal_play_end_cb_data);
649                 papp_snd->psignal_play_end_cb = NULL;
650                 papp_snd->psignal_play_end_cb_data = NULL;
651         }
652
653         CALL_ENG_DEBUG(ENG_DEBUG, "Application Sound Status:%d \n", papp_snd->signal_sound_status);
654 }
655
656 /**
657  * This function sets the end signal of the given end cause type
658  *
659  * @return              void
660  * @param[in]           papp_snd                Handle to Sound Manager
661  * @param[in]           end_cause_type          Type of the end cause
662  */
663 void voicecall_snd_set_signal_type(voicecall_snd_mgr_t *papp_snd, voicecall_snd_signal_type_t signal_type)
664 {
665         char signal_tone[VOICE_CALL_SND_RINGTONE_PATH_LEN];
666
667         CALL_ENG_DEBUG(ENG_DEBUG, "Signal Type: %d\n", signal_type);
668
669         memset(signal_tone, 0, sizeof(signal_tone));
670
671         papp_snd->signal_type = signal_type;
672         switch (papp_snd->signal_type) {
673         case VOICE_CALL_SIGNAL_USER_BUSY_TONE:
674                 {
675                         _vc_core_util_strcpy(signal_tone, VOICE_CALL_SND_RINGTONE_PATH_LEN, VOICE_CALL_SND_USER_BUSY_SIGNAL_PATH);
676                 }
677                 break;
678         case VOICE_CALL_SIGNAL_WRONG_NUMBER_TONE:
679                 {
680                         _vc_core_util_strcpy(signal_tone, VOICE_CALL_SND_RINGTONE_PATH_LEN, VOICE_CALL_SND_ERROR_SIGNAL_PATH);
681                 }
682                 break;
683         case VOICE_CALL_SIGNAL_CALL_FAIL_TONE:
684         case VOICE_CALL_SIGNAL_NW_CONGESTION_TONE:
685                 {
686                         _vc_core_util_strcpy(signal_tone, VOICE_CALL_SND_RINGTONE_PATH_LEN, VOICE_CALL_SND_NW_CONGESTION_SIGNAL_PATH);
687                 }
688                 break;
689         default:
690                 CALL_ENG_DEBUG(ENG_ERR, "Invalid Signal Type \n");
691                 break;
692         }
693
694         _vc_core_util_strcpy(papp_snd->signal_tone, sizeof(papp_snd->signal_tone), signal_tone);
695
696 }
697
698 static void __voicecall_snd_get_voice_path(voicecall_snd_mgr_t *papp_snd, int *voice_snd_path)
699 {
700         voicecall_audio_path_t tmp_audio_path;
701
702 #ifdef _NEW_SND_
703         CALL_ENG_DEBUG(ENG_DEBUG, "current path = %d\n", voicecall_snd_get_path_status(papp_snd));
704         
705         switch (voicecall_snd_get_path_status(papp_snd)) {
706         case VOICE_CALL_SND_PATH_BT:
707                 {
708                         tmp_audio_path = VC_AUDIO_PATH_BLUETOOTH;
709                 }
710                 break;
711         case VOICE_CALL_SND_PATH_SPEAKER:
712                 {
713                         tmp_audio_path = VC_AUDIO_PATH_SPK_PHONE;
714                 }
715                 break;
716         case VOICE_CALL_SND_PATH_EARJACK:
717                 {
718                         tmp_audio_path = VC_AUDIO_PATH_HEADSET;
719                 }
720                 break;
721         case VOICE_CALL_SND_PATH_RECEIVER:
722         default:
723                 {
724                         tmp_audio_path = VC_AUDIO_PATH_HANDSET;
725                 }
726         }
727 #else
728         CALL_ENG_DEBUG(ENG_DEBUG, "Headset Status  = %d\n", papp_snd->bcall_audio_status[VOICE_CALL_AUDIO_HEADSET]);
729         CALL_ENG_DEBUG(ENG_DEBUG, "Loud Speaker Status  = %d\n", papp_snd->bcall_audio_status[VOICE_CALL_AUDIO_SPEAKER]);
730
731         /*Priority is given to Headset, incase both loudspeaker and headset is enabled */
732         if (TRUE == papp_snd->bcall_audio_status[VOICE_CALL_AUDIO_HEADSET]) {
733                 tmp_audio_path = VC_AUDIO_PATH_BLUETOOTH;
734         } else if (TRUE == papp_snd->bcall_audio_status[VOICE_CALL_AUDIO_SPEAKER]) {
735                 tmp_audio_path = VC_AUDIO_PATH_SPK_PHONE;
736         } else if (TRUE == papp_snd->bcall_audio_status[VOICE_CALL_AUDIO_EARJACK]) {
737                 tmp_audio_path = VC_AUDIO_PATH_HEADSET;
738         } else {
739                 tmp_audio_path = VC_AUDIO_PATH_HANDSET;
740         }
741 #endif
742         *voice_snd_path = tmp_audio_path;
743
744         CALL_ENG_DEBUG(ENG_DEBUG, "voice_snd_path = %d\n", *voice_snd_path);
745
746 }
747
748 void voicecall_snd_change_mm_path(voicecall_snd_mgr_t *papp_snd, voicecall_snd_mm_path_type_t mm_path_type)
749 {
750         call_vc_core_state_t *pcall_core = (call_vc_core_state_t *)papp_snd->pcall_core;
751         voicecall_engine_t *pcall_engine = pcall_core->pcall_engine;
752         int in_path = 0;
753         int out_path = 0;
754         int gain_type = 0;
755         int mm_error = 0;
756         int option_field = MM_SOUND_PATH_OPTION_AUTO_HEADSET_CONTROL;
757
758         CALL_ENG_DEBUG(ENG_DEBUG, "mm_path_type = %d\n", mm_path_type);
759         CALL_ENG_DEBUG(ENG_DEBUG, "papp_snd->current_path_type = %d\n", papp_snd->current_path_type);
760
761 #ifdef _NEW_SND_
762         switch (voicecall_snd_get_path_status(papp_snd)) {
763         case VOICE_CALL_SND_PATH_BT:
764                 {
765                         out_path = MM_SOUND_PATH_BTHEADSET;
766                         in_path = MM_SOUND_PATH_BTMIC;
767                 }
768                 break;
769         case VOICE_CALL_SND_PATH_SPEAKER:
770                 {
771                         out_path = MM_SOUND_PATH_SPK;
772                         in_path = MM_SOUND_PATH_MIC;
773                         option_field = MM_SOUND_PATH_OPTION_NONE;
774                 }
775                 break;
776         case VOICE_CALL_SND_PATH_EARJACK:
777         case VOICE_CALL_SND_PATH_RECEIVER:
778         default:
779                 {
780                         out_path = MM_SOUND_PATH_RECV;
781                         in_path = MM_SOUND_PATH_MIC;
782                 }
783                 break;
784         }
785         
786 #else
787         /*Define OutPath */
788         if (TRUE == papp_snd->bcall_audio_status[VOICE_CALL_AUDIO_HEADSET]) {
789                 out_path = MM_SOUND_PATH_BTHEADSET;
790         } else if (TRUE == papp_snd->bcall_audio_status[VOICE_CALL_AUDIO_SPEAKER]) {
791                 out_path = MM_SOUND_PATH_SPK;
792                 option_field = MM_SOUND_PATH_OPTION_NONE;
793         } else {                /*Normal Phone Reciever */
794
795                 out_path = MM_SOUND_PATH_RECV;
796         }
797
798         if (TRUE == papp_snd->bcall_audio_status[VOICE_CALL_AUDIO_HEADSET]) {
799                 in_path = MM_SOUND_PATH_BTMIC;
800         } else {
801                 CALL_ENG_DEBUG(ENG_DEBUG, "Don't off the MIC. Mute only modem\n");
802                 in_path = MM_SOUND_PATH_MIC;
803         }
804 #endif
805
806         CALL_ENG_DEBUG(ENG_DEBUG, "Out Path = %d, In Path = %d \n", out_path, in_path);
807
808         /* This patch is required : if voice path is not reset,
809          * the volume played for ringtone and signal tone will not be audible enough to hear
810          */
811         if ((VOICE_CALL_MM_VOICE == papp_snd->current_path_type) && ((VOICE_CALL_MM_RING_TONE == mm_path_type) || (VOICE_CALL_MM_SIGNAL_TONE == mm_path_type))) {
812                 CALL_ENG_DEBUG(ENG_DEBUG, "Resetting Voice Path before changing to some other path \n");
813         }
814
815         /*Define Gain Type */
816         switch (mm_path_type) {
817         case VOICE_CALL_MM_ALERT_TONE:
818                 {
819                         gain_type = MM_SOUND_GAIN_CALLTONE;
820                         in_path = MM_SOUND_PATH_NONE;
821                 }
822                 break;
823         case VOICE_CALL_MM_SECOND_CALL_TONE:
824                 {
825                         /* MMFW sound request. always set it. */
826                         gain_type = MM_SOUND_GAIN_KEYTONE;      /* In case of earjack inserting, during second call */
827                         in_path = MM_SOUND_PATH_NONE;
828                 }
829                 break;
830         case VOICE_CALL_MM_RING_TONE:
831                 {
832                         int io_state = VC_INOUT_STATE_NONE;
833
834                         gain_type = MM_SOUND_GAIN_RINGTONE;
835                         in_path = MM_SOUND_PATH_NONE;
836                         option_field = MM_SOUND_PATH_OPTION_SPEAKER_WITH_HEADSET;
837
838                         voicecall_core_get_engine_state(pcall_engine, &io_state);
839                         if ((voicecall_core_is_incoming_call_exists(pcall_engine)) && (io_state != VC_INOUT_STATE_INCOME_END)) {
840                                 out_path = MM_SOUND_PATH_SPK;
841                         }
842                 }
843                 break;
844         case VOICE_CALL_MM_MUTE_PLAY:
845                 {
846                         gain_type = MM_SOUND_GAIN_RINGTONE;
847                         in_path = MM_SOUND_PATH_NONE;
848                         out_path = MM_SOUND_PATH_HEADSET;
849                 }
850                 break;
851         case VOICE_CALL_MM_RESET:
852                 {
853                         gain_type = MM_SOUND_GAIN_VOICECALL;
854                         in_path = MM_SOUND_PATH_NONE;
855                         out_path = MM_SOUND_PATH_NONE;
856                 }
857                 break;
858         case VOICE_CALL_MM_SIGNAL_TONE:
859                 {
860                         gain_type = MM_SOUND_GAIN_CALLTONE;
861                         in_path = MM_SOUND_PATH_NONE;
862                 }
863                 break;
864         case VOICE_CALL_MM_RECORD:
865                 {
866                         gain_type = MM_SOUND_GAIN_VOICECALL;
867                 }
868                 break;
869         case VOICE_CALL_MM_VOICE:
870                 {
871                         gain_type = MM_SOUND_GAIN_VOICECALL;
872                 }
873                 break;
874         default:
875                 CALL_ENG_DEBUG(ENG_DEBUG, "Invalid MM Path Type: %d\n", mm_path_type);
876         }
877
878         if (papp_snd->bsound_cm_state == TRUE) {
879                 CALL_ENG_DEBUG(ENG_DEBUG, "mm_sound_set_path- Gain:[%d],OutPath:[%d],InPath:[%d],option:[%d] \n", gain_type, out_path, in_path, option_field);
880                 CALL_ENG_KPI("mm_sound_set_path start");
881                 mm_error = mm_sound_set_path(gain_type, out_path, in_path, option_field);
882                 CALL_ENG_KPI("mm_sound_set_path done");
883                 if (mm_error != MM_ERROR_NONE) {
884                         CALL_ENG_DEBUG(ENG_ERR, "MM Path Change Failed,mm_error =  [0x%x]\n", mm_error);
885                 }
886                 papp_snd->current_path_type = mm_path_type;
887         } else {
888                 CALL_ENG_DEBUG(ENG_ERR, "** we can't change mm path. check it. **** \n");
889         }
890
891 }
892
893 /**
894  * This function changes the sound path according to the current status
895  *
896  * @return              void
897  * @param[in]           papp_snd                        Handle to Sound Manager
898  */
899 void voicecall_snd_change_path(voicecall_snd_mgr_t *papp_snd)
900 {
901         CALL_ENG_DEBUG(ENG_DEBUG, "..\n");
902         CALL_ENG_KPI("voicecall_snd_change_path start");
903         call_vc_core_state_t *pcall_core = (call_vc_core_state_t *)papp_snd->pcall_core;
904
905 #ifdef _NEW_SND_
906         if (voicecall_snd_get_path_status(papp_snd) == VOICE_CALL_SND_PATH_BT) {
907                 int bt_sco_status = 0;
908
909                 bt_sco_status = _vc_bt_get_bt_sco_status();
910                 if (FALSE == bt_sco_status) {
911                         gboolean bevent_wait = FALSE;
912
913                         CALL_ENG_DEBUG(ENG_ERR, "BT Sco is OFF, request BT for path change\n");
914                         bevent_wait = voicecall_core_get_status(pcall_core, CALL_VC_CORE_FLAG_BT_EVENT_WAITING);
915                         if (FALSE == bevent_wait) {
916                                 /*Request BT for change path to headset */
917                                 _vc_bt_request_switch_headset_path(pcall_core, TRUE);
918                         } else {
919                                 CALL_ENG_DEBUG(ENG_ERR, "bevent_wait = %d, waiting for BT Event \n", bevent_wait);
920                         }
921                 } else {
922                         CALL_ENG_DEBUG(ENG_DEBUG, "BT SCO is open, Change the path to sync with BT Path\n");
923                         voicecall_snd_change_path_real(papp_snd);
924                 }
925         }else {
926                 CALL_ENG_DEBUG(ENG_DEBUG, "new PATH is not BT.");
927                 gboolean bevent_wait = FALSE;
928
929                 bevent_wait = voicecall_core_get_status(pcall_core, CALL_VC_CORE_FLAG_BT_EVENT_WAITING);
930                 if (FALSE == bevent_wait) {
931                         /*Request BT for change path to headset */
932                         voicecall_snd_change_path_real(papp_snd);
933                 } else {
934                         CALL_ENG_DEBUG(ENG_ERR, "bevent_wait = %d, waiting for BT Event \n", bevent_wait);
935                 }
936         }
937 #else
938         if ((TRUE == _vc_bt_is_bt_connected(pcall_core))
939             && (TRUE == papp_snd->bcall_audio_status[VOICE_CALL_AUDIO_HEADSET])) {
940
941                 int bt_sco_status = 0;
942
943                 bt_sco_status = _vc_bt_get_bt_sco_status();
944                 if (FALSE == bt_sco_status) {
945                         gboolean bevent_wait = FALSE;
946
947                         CALL_ENG_DEBUG(ENG_ERR, "BT Sco is OFF, request BT for path change\n");
948                         bevent_wait = voicecall_core_get_status(pcall_core, CALL_VC_CORE_FLAG_BT_EVENT_WAITING);
949                         if (FALSE == bevent_wait) {
950                                 /*Request BT for change path to headset */
951                                 _vc_bt_request_switch_headset_path(pcall_core, TRUE);
952                         } else {
953                                 CALL_ENG_DEBUG(ENG_ERR, "bevent_wait = %d, waiting for BT Event \n", bevent_wait);
954                         }
955                 } else {
956                         CALL_ENG_DEBUG(ENG_DEBUG, "BT SCO is open, Change the path to sync with BT Path\n");
957                         voicecall_snd_change_path_real(papp_snd);
958                 }
959         } else if ((TRUE == _vc_bt_is_bt_connected(pcall_core)) && (TRUE == voicecall_core_get_status(pcall_core, CALL_VC_CORE_FLAG_ACCEPT_BY_BT))) {
960                 /*Request BT for change path to headset, actual voice path will be changed in the response from BT */
961                 CALL_ENG_DEBUG(ENG_ERR, "Headset Connected Call is accepted by BT, requesting BT to change path\n");
962                 _vc_bt_request_switch_headset_path(pcall_core, TRUE);
963         } else {
964                 CALL_ENG_DEBUG(ENG_DEBUG, "No Headset connected/Headset connected call accepted by Phone, Normal Path Change..\n");
965                 voicecall_snd_change_path_real(papp_snd);
966         }
967 #endif
968         CALL_ENG_KPI("voicecall_snd_change_path done");
969
970 }
971
972 void voicecall_snd_change_path_real(voicecall_snd_mgr_t *papp_snd)
973 {
974         CALL_ENG_DEBUG(ENG_DEBUG, "..\n");
975
976         /* Change the mm sound path */
977         voicecall_snd_change_mm_path(papp_snd, VOICE_CALL_MM_VOICE);
978
979         voicecall_snd_change_modem_path(papp_snd);
980 }
981
982 void voicecall_snd_change_modem_path(voicecall_snd_mgr_t *papp_snd)
983 {
984         CALL_ENG_DEBUG(ENG_DEBUG, "..\n");
985         call_vc_core_state_t *pcall_core = (call_vc_core_state_t *)papp_snd->pcall_core;
986
987         int audio_path = VC_AUDIO_PATH_HANDSET;
988
989         /* Change the tapi sound path */
990         __voicecall_snd_get_voice_path(papp_snd, &audio_path);
991
992         if (FALSE == voicecall_core_change_audio_path(pcall_core->pcall_engine, audio_path)) {
993                 CALL_ENG_DEBUG(ENG_ERR, "TAPI Audio Change Path ERROR \n");
994         }
995 }
996
997 /**
998  * This function sets the status of the given call audio type
999  *
1000  * @return              void
1001  * @param[in]           papp_snd                Handle to Sound Manager
1002  * @param[in]           snd_audio_type          Type of the Device to be changed
1003  * @param[in]           status                          Status, TRUE - Enable, FALSE -Disable
1004  */
1005 void voicecall_snd_set_status(voicecall_snd_mgr_t *papp_snd, voicecall_snd_audio_type_t snd_audio_type, gboolean status)
1006 {
1007         CALL_ENG_DEBUG(ENG_DEBUG, "snd_audio_type:[%d], status:[%d]\n", snd_audio_type, status);
1008
1009         /*if BT headset is connected , switch off loud speaker - it will be reflectd in the next sound path change */
1010         if (((VOICE_CALL_AUDIO_HEADSET == snd_audio_type) || (VOICE_CALL_AUDIO_EARJACK == snd_audio_type)) && (TRUE == status)) {
1011                 CALL_ENG_DEBUG(ENG_DEBUG, "loud speaker status is to be FALSE\n");
1012                 papp_snd->bcall_audio_status[VOICE_CALL_AUDIO_SPEAKER] = FALSE;
1013         }
1014         papp_snd->bcall_audio_status[snd_audio_type] = status;
1015 }
1016
1017 /**
1018  * This function returns the current status of the given call audio type
1019  *
1020  * @return              Returns TRUE if given call audio type is enables or FALSE otherwise
1021  * @param[in]           papp_snd                Handle to Sound Manager
1022  * @param[in]           snd_audio_type  Type of the Device to be changed
1023  */
1024 gboolean voicecall_snd_get_status(voicecall_snd_mgr_t *papp_snd, voicecall_snd_audio_type_t snd_audio_type)
1025 {
1026         CALL_ENG_DEBUG(ENG_DEBUG, "Status[%d] = %d \n", snd_audio_type, papp_snd->bcall_audio_status[snd_audio_type]);
1027         return papp_snd->bcall_audio_status[snd_audio_type];
1028 }
1029
1030 #ifdef _NEW_SND_
1031 /**
1032  * This function sets the status of the given call audio type
1033  *
1034  * @return              void
1035  * @param[in]           papp_snd                Handle to Sound Manager
1036  * @param[in]           snd_audio_type          Type of the Device to be changed
1037  * @param[in]           status                          Status, TRUE - Enable, FALSE -Disable
1038  */
1039 void voicecall_snd_set_path_status(voicecall_snd_mgr_t *papp_snd, voicecall_snd_path_t path)
1040 {
1041         CALL_ENG_DEBUG(ENG_DEBUG, "current path:[%d], new path:[%d]\n", papp_snd->current_snd_path, path);
1042
1043         papp_snd->old_snd_path = papp_snd->current_snd_path;
1044         papp_snd->current_snd_path = path;
1045 }
1046
1047 voicecall_snd_path_t voicecall_snd_get_path_status(voicecall_snd_mgr_t *papp_snd)
1048 {
1049         CALL_ENG_DEBUG(ENG_DEBUG, "old path:[%d], current path:[%d]\n", papp_snd->old_snd_path, papp_snd->current_snd_path);
1050
1051         return papp_snd->current_snd_path;
1052 }
1053 #endif
1054
1055 /**
1056 * This function sets the volume level for the given volume alert type
1057 *
1058 * @return               void
1059 * @param[in]    papp_snd                Handle to Sound Manager
1060 * @param[in]    vol_alert_type  volume alert type #voicecall_snd_volume_alert_type_t
1061 * @param[in]    volume_level    volume level to be set
1062 */
1063 void voicecall_snd_set_volume(voicecall_snd_mgr_t *papp_snd, voicecall_snd_volume_alert_type_t vol_alert_type, int volume_level)
1064 {
1065         CALL_ENG_DEBUG(ENG_DEBUG, "volume_level = %d \n", volume_level);
1066         call_vc_core_state_t *pcall_core = (call_vc_core_state_t *)papp_snd->pcall_core;
1067
1068         switch (vol_alert_type) {
1069         case VOICE_CALL_VOL_TYPE_RINGTONE:
1070                 {
1071                         int ret_value = 0;
1072                         int volume;
1073
1074                         if (VOICE_CALL_SND_INVALID_PLAYER_HANDLE == papp_snd->pmm_player) {
1075                                 CALL_ENG_DEBUG(ENG_ERR, "Invalid MM Player Handle \n");
1076                                 return;
1077                         }
1078
1079                         /* Make Increasing Melody flag to FALSE, so melody volume will not be increased when volume it adjusted by user during increasing melody */
1080                         papp_snd->bincreasingmelody = FALSE;
1081
1082                         volume = volume_level;
1083
1084                         ret_value = mm_sound_volume_set_value(VOLUME_TYPE_RINGTONE, volume);
1085                         if (MM_ERROR_NONE != ret_value) {
1086                                 CALL_ENG_DEBUG(ENG_ERR, "mmplayer_set_volume failed Error: [0x%x]\n", ret_value);
1087                         }
1088 #ifdef VOICE_CALL_RINGTONE_ELEVATOR
1089                         __voicecall_snd_cancel_ring_elevator(papp_snd);
1090 #endif
1091                 }
1092                 break;
1093         case VOICE_CALL_VOL_TYPE_VOICE:
1094                 {
1095                         int incall_vol_level = 0;
1096                         int audio_path = 0;
1097
1098                         if (VOICE_CALL_VOL_LEVEL_1 >= volume_level) {
1099                                 incall_vol_level = VOICE_CALL_VOL_LEVEL_1;
1100                         } else if (VOICE_CALL_VOL_LEVEL_6 < volume_level) {
1101                                 incall_vol_level = VOICE_CALL_VOL_LEVEL_6;
1102                         } else {
1103                                 incall_vol_level = volume_level;
1104                         }
1105
1106                         __voicecall_snd_get_voice_path(papp_snd, &audio_path);
1107
1108                         _vc_core_util_set_call_volume(volume_level);
1109
1110                         /* MODEM want to get volume level as 0~5, not a 1~6. So pass -1 value */
1111                         if (FALSE == voicecall_core_set_audio_volume(pcall_core->pcall_engine, audio_path, (incall_vol_level-1))) {
1112                                 CALL_ENG_DEBUG(ENG_DEBUG, "voicecall_doc_set_audio_volume failed\n");
1113                         }
1114                 }
1115                 break;
1116         case VOICE_CALL_VOL_TYPE_HEADSET:
1117                 {
1118                         int bt_vol_level = 0;
1119                         if (TRUE == voicecall_core_get_status(pcall_core, CALL_VC_CORE_FLAG_VOL_CHNGD_BYBT)) {
1120                                 CALL_ENG_DEBUG(ENG_DEBUG, "BT Requested Volume flag is enabled, not sending response \n");
1121                                 voicecall_core_set_status(pcall_core, CALL_VC_CORE_FLAG_VOL_CHNGD_BYBT, FALSE);
1122                         } else {
1123                                 bt_vol_level = volume_level;
1124                                 CALL_ENG_DEBUG(ENG_DEBUG, "bt_vol_level = %d\n", bt_vol_level);
1125
1126                                 _vc_bt_send_response_to_bt(pcall_core, BT_AG_RES_SPK_GAIN, bt_vol_level, NULL);
1127                         }
1128
1129                 }
1130                 break;
1131         default:
1132                 CALL_ENG_DEBUG(ENG_DEBUG, "No Actions Defined for the volume alert type: %d \n", vol_alert_type);
1133
1134         }
1135 }
1136
1137 /**
1138  * This function retreives the volume according to the given volume alert type
1139  *
1140  * @return              current volume level
1141  * @param[in]           papp_snd                Handle to Sound Manager
1142  * @param[in]           vol_alert_type          volume alert type #voicecall_snd_volume_alert_type_t
1143  */
1144 int voicecall_snd_get_volume(voicecall_snd_mgr_t *papp_snd, voicecall_snd_volume_alert_type_t vol_alert_type)
1145 {
1146         CALL_ENG_DEBUG(ENG_DEBUG, "\n");
1147         call_vc_core_state_t *pcall_core = (call_vc_core_state_t *)papp_snd->pcall_core;
1148
1149         switch (vol_alert_type) {
1150         case VOICE_CALL_VOL_TYPE_RINGTONE:
1151                 {
1152                         int ret_val = 0;
1153                         unsigned int volume = 0;
1154
1155                         ret_val = mm_sound_volume_get_value(VOLUME_TYPE_RINGTONE, &volume);
1156                         if (MM_ERROR_NONE != ret_val) {
1157                                 CALL_ENG_DEBUG(ENG_DEBUG, "ret_val = [0x%x]\n", ret_val);
1158                                 return VC_INVALID_VOLUME;
1159                         }
1160                         CALL_ENG_DEBUG(ENG_DEBUG, "MM Volume Level : %d\n", volume);
1161
1162                         return volume;
1163
1164                 }
1165                 break;
1166         case VOICE_CALL_VOL_TYPE_VOICE:
1167                 {
1168                         return _vc_core_util_get_call_volume();
1169                 }
1170                 break;
1171         case VOICE_CALL_VOL_TYPE_HEADSET:
1172                 {
1173                         _vc_bt_send_response_to_bt(pcall_core, BT_AG_RES_HEADSET_VOL, 0, NULL);
1174                         return VC_INVALID_VOLUME;       /*Return Invalid Volume level as default */
1175                 }
1176                 break;
1177         default:
1178                 return VC_INVALID_VOLUME;       /*Return Invalid Volume level as default */
1179         }
1180
1181         return VC_INVALID_VOLUME;
1182 }
1183
1184 gboolean voicecall_snd_get_alternate_play(voicecall_snd_mgr_t *papp_snd)
1185 {
1186         return papp_snd->balternate_play;
1187 }
1188
1189 static gboolean __voicecall_snd_start_melody(voicecall_snd_mgr_t *papp_snd, gboolean bis_increasing, int call_handle)
1190 {
1191         char *setting_file_path = NULL;
1192         char ringtone_path[VOICE_CALL_SND_RINGTONE_PATH_LEN] = { 0, };
1193         call_vc_call_objectinfo_t callobject_info;
1194         voicecall_contact_info_t ct_info;
1195
1196         call_vc_core_state_t *pcall_core = (call_vc_core_state_t *)papp_snd->pcall_core;
1197
1198         CALL_ENG_DEBUG(ENG_DEBUG, "call_handle = %d\n", call_handle);
1199
1200         CALL_ENG_DEBUG(ENG_DEBUG, "Contact ring_tone_path = [%s]\n", papp_snd->ring_tone);
1201
1202         if (strlen(papp_snd->ring_tone) <= 0) {
1203                 setting_file_path = vconf_get_str(VCONFKEY_SETAPPL_CALL_RINGTONE_PATH_STR);
1204                 if ((setting_file_path == NULL) || (strlen(setting_file_path) <= 0) ||
1205                 (FALSE == g_file_test(setting_file_path, G_FILE_TEST_EXISTS)))
1206                 {
1207                         CALL_ENG_DEBUG(ENG_ERR, "setting ring tone path is invalid : [%s]\n", setting_file_path);
1208                         /*snprintf(ringtone_path, sizeof(ringtone_path), "file://%s", VOICE_CALL_SND_DEFAULT_RINGTONE_PATH);*/
1209                         return;
1210                 } else {
1211                         snprintf(ringtone_path, sizeof(ringtone_path), "file://%s", setting_file_path);
1212
1213                 }
1214                 CALL_ENG_DEBUG(ENG_DEBUG, "Ringtone From Settings : %s\n", ringtone_path);
1215                 _vc_core_util_strcpy(papp_snd->ring_tone, sizeof(papp_snd->ring_tone), ringtone_path);
1216         }
1217
1218         /* Create MM Player */
1219         papp_snd->pmm_player = VOICE_CALL_SND_INVALID_PLAYER_HANDLE;
1220         __voicecall_snd_create_player(papp_snd, &papp_snd->pmm_player, VOICE_CALL_PLAY_TYPE_RINGTONE);
1221
1222         papp_snd->ringtone_sound_status = VOICE_CALL_SND_STATUS_READY;
1223
1224         return TRUE;
1225 }
1226
1227 static gboolean __voicecall_snd_create_player(voicecall_snd_mgr_t *papp_snd, MMHandleType * pPlayer, voicecall_snd_play_type_t play_type)
1228 {
1229         int ret_value = 0;
1230         MMMessageCallback callback = NULL;
1231         char *mmf_error = NULL;
1232
1233         CALL_ENG_DEBUG(ENG_DEBUG, "Start..\n");
1234
1235         if (*pPlayer != VOICE_CALL_SND_INVALID_SND_HANDLE) {
1236                 CALL_ENG_DEBUG(ENG_DEBUG, "Player = %d \n", *pPlayer);
1237                 mm_player_destroy(*pPlayer);
1238                 *pPlayer = VOICE_CALL_SND_INVALID_SND_HANDLE;
1239         }
1240
1241         ret_value = mm_player_create(pPlayer);
1242         if (MM_ERROR_NONE != ret_value || *pPlayer == VOICE_CALL_SND_INVALID_SND_HANDLE) {
1243                 CALL_ENG_DEBUG(ENG_ERR, "mmplayer_create failed , Error:[0x%x]\n", ret_value);
1244                 return FALSE;
1245         }
1246         CALL_ENG_DEBUG(ENG_DEBUG, "*pPlayer: %d\n", *pPlayer);
1247
1248         switch (play_type) {
1249                 /*Set the MM Player Attributes according to the Display Priority Type */
1250         case VOICE_CALL_PLAY_TYPE_RINGTONE:
1251                 {
1252                         mm_player_set_attribute(*pPlayer, &mmf_error,
1253                                                 "sound_volume_type", MM_SOUND_VOLUME_TYPE_RINGTONE,
1254                                                 "profile_uri", papp_snd->ring_tone, VOICE_CALL_SND_RINGTONE_PATH_LEN,
1255                                                 "profile_play_count", -1, "sound_route", MM_AUDIOROUTE_USE_EXTERNAL_SETTING, "sound_spk_out_only", TRUE, "sound_stop_when_unplugged", FALSE, NULL);
1256                         callback = __voicecall_snd_mmplayer_cb;
1257
1258                 }
1259                 break;
1260         default:
1261                 break;
1262         }
1263
1264         mm_player_set_message_callback(*pPlayer, callback, papp_snd);
1265
1266         ret_value = mm_player_realize(*pPlayer);
1267         if (MM_ERROR_NONE != ret_value) {
1268                 CALL_ENG_DEBUG(ENG_ERR, "mmplayer_realize failed , Error:[0x%x]\n", ret_value);
1269                 return FALSE;
1270         }
1271
1272         CALL_ENG_DEBUG(ENG_DEBUG, "Finish..\n");
1273         return TRUE;
1274 }
1275
1276 static gboolean __voicecall_snd_play_melody(voicecall_snd_mgr_t *papp_snd, gboolean bis_increasing)
1277 {
1278         CALL_ENG_DEBUG(ENG_DEBUG, "..\n");
1279
1280         if (strlen(papp_snd->ring_tone) > 0) {
1281                 int mm_error = MM_ERROR_NONE;
1282
1283                 mm_error = mm_player_start(papp_snd->pmm_player);
1284                 if (MM_ERROR_NONE != mm_error) {
1285                         CALL_ENG_DEBUG(ENG_ERR, "mm_player_start failed,Error: [0x%x]\n", mm_error);
1286                 } else {
1287                         if (TRUE == bis_increasing) {
1288                                 papp_snd->bincreasingmelody = TRUE;
1289                                 g_timeout_add(VOICE_CALL_SND_INCREMENT_TIMER_INTERVAL, __voicecall_snd_increasing_melody_cb, (gpointer) papp_snd);
1290                         } else {
1291 #ifdef VOICE_CALL_RINGTONE_ELEVATOR
1292                                 CALL_ENG_DEBUG(ENG_DEBUG, "Starting Ringtone Elevator\n");
1293                                 /*Start only when the volume is not incremental volume */
1294                                 __voicecall_snd_start_ring_elevator(papp_snd);
1295 #endif
1296                         }
1297
1298                         papp_snd->ringtone_sound_status = VOICE_CALL_SND_STATUS_PLAY;
1299                         return TRUE;
1300                 }
1301         } else {
1302                 CALL_ENG_DEBUG(ENG_ERR, "Ringtone is empty(Problem) \n");
1303         }
1304
1305         return FALSE;
1306 }
1307
1308 static int __voicecall_snd_mmplayer_cb(int message, void *data, void *user_data)
1309 {
1310         voicecall_snd_mgr_t *papp_snd = (voicecall_snd_mgr_t *)user_data;
1311         if (VOICE_CALL_SND_STATUS_PLAY != papp_snd->ringtone_sound_status) {
1312                 CALL_ENG_DEBUG(ENG_DEBUG, "Sound Play stopped by application, callback not handled \n");
1313                 return FALSE;
1314         }
1315
1316         switch (message) {
1317         case MM_MESSAGE_END_OF_STREAM:
1318                 {
1319                         CALL_ENG_DEBUG(ENG_DEBUG, "Ringtone loop count is supported by MMF , need not restart the ringtone \n");
1320                 }
1321                 break;
1322         default:
1323                 return FALSE;
1324                 break;
1325         }
1326         return TRUE;
1327 }
1328
1329 gboolean __voicecall_snd_mmplayer_signal_end_callback_idle_cb(gpointer pdata)
1330 {
1331         voicecall_snd_mgr_t *papp_snd = (voicecall_snd_mgr_t *)pdata;
1332
1333         CALL_ENG_DEBUG(ENG_DEBUG, " \n");
1334
1335         /*Callback needs to be called, only when the tone is played completely and it is ended
1336            if the signal is explictly stopped, don't call the user callback */
1337         if (papp_snd->psignal_play_end_cb != NULL) {
1338                 CALL_ENG_DEBUG(ENG_DEBUG, "Calling user callback \n");
1339                 papp_snd->psignal_play_end_cb(papp_snd->psignal_play_end_cb_data);
1340                 papp_snd->psignal_play_end_cb = NULL;
1341                 papp_snd->psignal_play_end_cb_data = NULL;
1342         }
1343
1344         return FALSE;
1345 }
1346
1347 static void __voicecall_snd_mmplayer_signal_cb(gpointer puser_data)
1348 {
1349         voicecall_snd_mgr_t *papp_snd = (voicecall_snd_mgr_t *)puser_data;
1350
1351         CALL_ENG_DEBUG(ENG_DEBUG, "Sound Play Over \n");
1352
1353         if (papp_snd->signal_sound_status != VOICE_CALL_SND_STATUS_PLAY) {
1354                 CALL_ENG_DEBUG(ENG_DEBUG, "Sound Play already stopped by application \n");
1355                 return;
1356         }
1357
1358         papp_snd->signal_sound_status = VOICE_CALL_SND_STATUS_STOPPED;
1359
1360         __voicecall_snd_mmplayer_signal_end_callback_idle_cb(papp_snd);
1361 }
1362
1363 static gboolean __voicecall_snd_increasing_melody_cb(void *data)
1364 {
1365         voicecall_snd_mgr_t *papp_snd = (voicecall_snd_mgr_t *)data;
1366         int ret_value = 0;
1367         int set_volume_level = VOICE_CALL_VOL_LEVEL_1;
1368
1369         if (FALSE == papp_snd->bincreasingmelody) {
1370                 CALL_ENG_DEBUG(ENG_DEBUG, "Already Deactivated\n");
1371                 return FALSE;
1372         }
1373
1374         if (FALSE == vconf_get_int(VCONFKEY_SETAPPL_PROFILE_CURRENT_CALL_VOLUME_INT, &set_volume_level)) {
1375                 CALL_ENG_DEBUG(ENG_ERR, "settings read failed Error: %d\n", ret_value);
1376         }
1377
1378         if ((set_volume_level != 0) && (papp_snd->increment_melody_value <= set_volume_level)) {
1379                 int volume_val;
1380
1381                 papp_snd->increment_melody_value++;
1382
1383                 volume_val = papp_snd->increment_melody_value;
1384                 ret_value = mm_sound_volume_set_value(VOLUME_TYPE_RINGTONE, volume_val);
1385
1386                 if (MM_ERROR_NONE != ret_value) {
1387                         CALL_ENG_DEBUG(ENG_ERR, "Set Volume Error: [0x%x]\n", ret_value);
1388                 }
1389
1390                 CALL_ENG_DEBUG(ENG_DEBUG, "Increasing Melody Continuing, Current Increased Melody : %d\n", papp_snd->increment_melody_value);
1391                 if (papp_snd->increment_melody_value >= set_volume_level) {
1392                         CALL_ENG_DEBUG(ENG_DEBUG, "Increasing Melody Ended\n");
1393                         return FALSE;
1394                 }
1395
1396                 return TRUE;
1397         }
1398
1399         CALL_ENG_DEBUG(ENG_DEBUG, "Increasing Melody Ended\n");
1400         return FALSE;
1401 }
1402
1403 static void __voicecall_snd_start_vibration(voicecall_snd_mgr_t *papp_snd)
1404 {
1405         /*First Stop the previous Vibration and then start it again */
1406
1407         CALL_ENG_DEBUG(ENG_DEBUG, "..\n");
1408         int vib_type = -1;
1409         int vib_level = -1;
1410         int haptic_vib_type = -1;
1411
1412         papp_snd->bvibration = FALSE;
1413
1414         papp_snd->vibration_handle = device_haptic_open(DEV_IDX_0, 0);
1415
1416         CALL_ENG_DEBUG(ENG_DEBUG, "srart vibration device_handle=%d \n", papp_snd->vibration_handle);
1417
1418         if (papp_snd->vibration_handle < 0) {
1419                 CALL_ENG_DEBUG(ENG_DEBUG, "device_haptic_open error \n");
1420                 return;
1421         }
1422
1423         if (vconf_get_int(VCONFKEY_SETAPPL_CALL_VIBRATION_PATTERN_INT, &vib_type)) {
1424                 CALL_ENG_DEBUG(ENG_ERR, "VCONFKEY_SETAPPL_CALL_VIBRATION_PATTERN_INT vconf_get_bool failed.\n");
1425         }
1426         if (vconf_get_int(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, &vib_level)) {
1427                 CALL_ENG_DEBUG(ENG_ERR, "VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT vconf_get_bool failed.\n");
1428         }
1429
1430         if (vib_level > 5)
1431                 vib_level = 5;
1432
1433         switch (vib_type) {
1434         case SETTING_CALL_ALERT_VIB_TYPE1:
1435                 haptic_vib_type = EFFCTVIBE_INCOMING_CALL01;
1436                 break;
1437         case SETTING_CALL_ALERT_VIB_TYPE2:
1438                 haptic_vib_type = EFFCTVIBE_INCOMING_CALL02;
1439                 break;
1440         case SETTING_CALL_ALERT_VIB_TYPE3:
1441                 haptic_vib_type = EFFCTVIBE_INCOMING_CALL03;
1442                 break;
1443         default:
1444                 haptic_vib_type = EFFCTVIBE_INCOMING_CALL01;
1445                 break;
1446         }
1447         if (device_haptic_play_pattern(papp_snd->vibration_handle, haptic_vib_type, 255, vib_level)) {
1448                 CALL_ENG_DEBUG(ENG_DEBUG, "device_haptic_play_pattern error \n");
1449                 return;
1450         }
1451         if (device_haptic_play_monotone(papp_snd->vibration_handle, 60000)) {
1452                 CALL_ENG_DEBUG(ENG_DEBUG, "device_haptic_play_monotone error \n");
1453                 return;
1454         }
1455
1456         papp_snd->bvibration = TRUE;
1457
1458 }
1459
1460 static gboolean __voicecall_snd_vib_then_melody_cb(void *data)
1461 {
1462         voicecall_snd_mgr_t *papp_snd = (voicecall_snd_mgr_t *)data;
1463         call_vc_core_state_t *pcall_core = (call_vc_core_state_t *)papp_snd->pcall_core;
1464
1465         __voicecall_snd_stop_vibration(papp_snd);
1466
1467         if (FALSE == papp_snd->bvibration_then_melody) {
1468                 return FALSE;
1469         }
1470
1471         if (FALSE == voicecall_core_is_connected_call_exist(pcall_core->pcall_engine)) {
1472
1473                 int ret_value = -1;
1474                 int set_volume_level = 0;
1475                 int volume_val;
1476
1477                 vconf_get_int(VCONFKEY_SETAPPL_PROFILE_CURRENT_CALL_VOLUME_INT, &set_volume_level);
1478
1479                 volume_val = set_volume_level;
1480
1481                 ret_value = mm_sound_volume_set_value(VOLUME_TYPE_RINGTONE, volume_val);
1482
1483                 CALL_ENG_DEBUG(ENG_ERR, "__voicecall_snd_vib_then_melody_cb() : volume = %d\n", volume_val);
1484
1485                 __voicecall_snd_play_melody(papp_snd, FALSE);
1486         }
1487
1488         return FALSE;
1489 }
1490
1491 static void __voicecall_snd_stop_vibration(voicecall_snd_mgr_t *papp_snd)
1492 {
1493         CALL_ENG_DEBUG(ENG_DEBUG, "..\n");
1494
1495         if (TRUE == papp_snd->bvibration) {
1496                 CALL_ENG_DEBUG(ENG_DEBUG, "Stopping Vibration , handle=%d \n", papp_snd->vibration_handle);
1497
1498                 if (device_haptic_stop_play(papp_snd->vibration_handle)) {
1499                         CALL_ENG_DEBUG(ENG_DEBUG, "device_haptic_play_stop error \n");
1500                         return;
1501                 }
1502
1503                 if (device_haptic_close(papp_snd->vibration_handle)) {
1504                         CALL_ENG_DEBUG(ENG_DEBUG, "device_haptic_close error \n");
1505                         return;
1506                 }
1507
1508                 papp_snd->vibration_handle = -1;
1509
1510                 papp_snd->bvibration = FALSE;
1511         } else {
1512                 CALL_ENG_DEBUG(ENG_DEBUG, "bvibration is not enabled.\n");
1513         }
1514
1515 }
1516
1517 /*
1518 * This function is callback of mm_sound_route_add_callback
1519 * @return       void
1520 * @param[in]    data    call user data
1521 *               policy  system audio route policy which has applied.
1522 */
1523 void voicecall_snd_route_change_cb(void *data, system_audio_route_t policy)
1524 {
1525         int error_code = 0;
1526         CALL_ENG_DEBUG(ENG_ERR, "System audio route policy has changed");
1527         if (policy != SYSTEM_AUDIO_ROUTE_POLICY_IGNORE_A2DP) {
1528                 error_code = mm_sound_route_set_system_policy(SYSTEM_AUDIO_ROUTE_POLICY_IGNORE_A2DP);
1529                 if (error_code) {
1530                         CALL_ENG_DEBUG(ENG_ERR, "mm_sound_route_set_system_policy failed. error_code:[0x%x]\n", error_code);
1531                 }
1532         }
1533 }
1534
1535 /**
1536 * This function unregisters the application with the sound conflict manager
1537 *
1538 * @return                       void
1539 * @param[in]            papp_snd                Handle to Sound Manager
1540 */
1541 void voicecall_snd_register_cm(voicecall_snd_mgr_t *papp_snd)
1542 {
1543         int error_code = 0;
1544
1545         CALL_ENG_DEBUG(ENG_DEBUG, "current bsound_cm_state:[%d]. \n", papp_snd->bsound_cm_state);
1546
1547         if (FALSE == papp_snd->bsound_cm_state) {
1548                 CALL_ENG_KPI("mm_session_init start");
1549                 error_code = mm_session_init(MM_SESSION_TYPE_CALL);
1550                 CALL_ENG_KPI("mm_session_init done");
1551                 if (error_code) {
1552                         CALL_ENG_DEBUG(ENG_ERR, "mm_session_init failed. error_code:[0x%x]\n", error_code);
1553                         return;
1554                 }
1555                 error_code = mm_sound_route_get_system_policy(&papp_snd->backup_route_policy);
1556                 if (error_code) {
1557                         CALL_ENG_DEBUG(ENG_ERR, "mm_sound_route_get_system_policy failed. error_code:[0x%x]\n", error_code);
1558                         return;
1559                 }
1560                 error_code = mm_sound_route_set_system_policy(SYSTEM_AUDIO_ROUTE_POLICY_IGNORE_A2DP);
1561                 if (error_code) {
1562                         CALL_ENG_DEBUG(ENG_ERR, "mm_sound_route_set_system_policy failed. error_code:[0x%x]\n", error_code);
1563                         return;
1564                 }
1565                 error_code = mm_sound_route_add_change_callback(voicecall_snd_route_change_cb, NULL);
1566                 if (error_code) {
1567                         CALL_ENG_DEBUG(ENG_ERR, "mm_sound_route_add_change_callback failed. error_code:[0x%x]\n", error_code);
1568                         return;
1569                 }
1570
1571                 papp_snd->bsound_cm_state = TRUE;
1572         }
1573         return;
1574 }
1575
1576 /**
1577 * This function unregisters the application from the sound conflict manager
1578 *
1579 * @return                       void
1580 * @param[in]            papp_snd                Handle to Sound Manager
1581 */
1582 void voicecall_snd_unregister_cm(voicecall_snd_mgr_t *papp_snd)
1583 {
1584         int error_code = 0;
1585
1586         CALL_ENG_DEBUG(ENG_DEBUG, "current bsound_cm_state:[%d]. \n", papp_snd->bsound_cm_state);
1587
1588         if (TRUE == papp_snd->bsound_cm_state) {
1589                 /*Reset the Path when the app is closed - safety code */
1590                 voicecall_snd_change_mm_path(papp_snd, VOICE_CALL_MM_RESET);
1591                 CALL_ENG_DEBUG(ENG_DEBUG, "Sound Path reset to Default\n");
1592
1593                 papp_snd->bsound_cm_state = FALSE;
1594
1595                 CALL_ENG_DEBUG(ENG_DEBUG, "Unregistering Sound CM\n");
1596                 error_code = mm_session_finish();
1597                 if (error_code) {
1598                         CALL_ENG_DEBUG(ENG_ERR, "mm_session_finish failed. error_code:[0x%x]\n", error_code);
1599                 }
1600                 error_code = mm_sound_route_remove_change_callback();
1601                 if (error_code) {
1602                         CALL_ENG_DEBUG(ENG_ERR, "mm_sound_route_remove_change_callback failed. error_code:[0x%x]\n", error_code);
1603                 }
1604                 error_code = mm_sound_route_set_system_policy(papp_snd->backup_route_policy);
1605                 if (error_code) {
1606                         CALL_ENG_DEBUG(ENG_ERR, "mm_sound_route_set_system_policy failed. error_code:[0x%x]\n", error_code);
1607                 }
1608         }
1609         /*Set to Defaults */
1610         voicecall_snd_set_to_defaults(papp_snd);
1611         return;
1612 }
1613
1614 gboolean __voicecall_snd_effect_idle_cb(gpointer puser_data)
1615 {
1616         voicecall_snd_mgr_t *papp_snd = (voicecall_snd_mgr_t *)puser_data;
1617         call_vc_core_state_t *pcall_core = (call_vc_core_state_t *)papp_snd->pcall_core;
1618
1619         papp_snd->effect_tone_status = VOICE_CALL_SND_STATUS_NONE;
1620         CALL_ENG_DEBUG(ENG_DEBUG, "papp_snd->effect_tone_status = %d\n", papp_snd->effect_tone_status);
1621
1622         /*If connected call exists then change the audio path */
1623         if ((TRUE == voicecall_core_is_connected_call_exist(pcall_core->pcall_engine)) || (TRUE == voicecall_core_is_outgoing_call_exists(pcall_core->pcall_engine))) {
1624                 CALL_ENG_DEBUG(ENG_DEBUG, "Connected call exists, changing path at the end of effect tone \n");
1625
1626                 CALL_ENG_DEBUG(ENG_ERR, "papp_snd->signal_sound_status = %d \n", papp_snd->signal_sound_status);
1627                 /*Check the signal play status, if signal is being prepared / played, don't change the path */
1628                 if (VOICE_CALL_SND_STATUS_NONE == papp_snd->signal_sound_status) {
1629                         voicecall_snd_change_path(papp_snd);
1630                 } else {
1631                         CALL_ENG_DEBUG(ENG_ERR, "Signal is playing, skipping path change, it will be done at the end of signal \n");
1632                 }
1633         } else {
1634                 CALL_ENG_DEBUG(ENG_DEBUG, "non connected call\n");
1635         }
1636         CALL_ENG_DEBUG(ENG_DEBUG, "Over\n");
1637         return FALSE;
1638 }
1639
1640 static void __voicecall_snd_effect_cb(gpointer puser_data)
1641 {
1642         voicecall_snd_mgr_t *papp_snd = (voicecall_snd_mgr_t *)puser_data;
1643
1644         CALL_ENG_DEBUG(ENG_DEBUG, "effect_tone_status = %d, Calling Idle\n", papp_snd->effect_tone_status);
1645         papp_snd->effect_tone_status = VOICE_CALL_SND_STATUS_STOPPED;
1646
1647         __voicecall_snd_effect_idle_cb(papp_snd);
1648         CALL_ENG_DEBUG(ENG_DEBUG, "End : papp_snd->effect_tone_status = %d\n", papp_snd->effect_tone_status);
1649 }
1650
1651 gboolean voicecall_snd_play_effect_tone(voicecall_snd_mgr_t *papp_snd, int effect_type)
1652 {
1653         int error_code = -1;
1654         gboolean bzuhause = FALSE;
1655         gboolean bstatus = FALSE;
1656         call_vc_core_state_t *pcall_core = (call_vc_core_state_t *)papp_snd->pcall_core;
1657
1658         CALL_ENG_DEBUG(ENG_DEBUG, "effect type:[%d] \n", effect_type);
1659
1660         switch (effect_type) {
1661         case VOICE_CALL_SND_EFFECT_CALL_CONNECT:
1662                 {
1663                         CALL_ENG_KPI("voicecall_core_get_zuhause start");
1664                         voicecall_core_get_zuhause(pcall_core->pcall_engine, &bzuhause);
1665                         CALL_ENG_KPI("voicecall_core_get_zuhause done");
1666
1667                         if (bzuhause == TRUE) {
1668                                 CALL_ENG_DEBUG(ENG_DEBUG, "It's zuhause area! don't play connect tone!\n");
1669                                 return FALSE;
1670                         }
1671
1672                         CALL_ENG_KPI("get VCONFKEY_CISSAPPL_CALL_CONNECT_TONE_BOOL start");
1673                         if (vconf_get_bool(VCONFKEY_CISSAPPL_CALL_CONNECT_TONE_BOOL, &bstatus)) {
1674                                 CALL_ENG_DEBUG(ENG_ERR, "vconf_get_bool failed.\n");
1675                         }
1676                         CALL_ENG_KPI("get VCONFKEY_CISSAPPL_CALL_CONNECT_TONE_BOOL done");
1677
1678                         if (!bstatus) {
1679                                 CALL_ENG_DEBUG(ENG_DEBUG, "Connect Tone Settings not enabled \n");
1680                                 return FALSE;
1681                         }
1682
1683                         /*First Reset the audio Path to PDA */
1684                         voicecall_snd_change_mm_path(papp_snd, VOICE_CALL_MM_ALERT_TONE);
1685
1686                         error_code = mm_sound_play_sound(VOICE_CALL_SND_CONNECT_SIGNAL_PATH, VOLUME_TYPE_CALL, __voicecall_snd_effect_cb, papp_snd, &papp_snd->mmfsoundplay_handle);
1687                 }
1688                 break;
1689         case VOICE_CALL_SND_EFFECT_CALL_DISCONNECT:
1690                 {
1691
1692                         if (vconf_get_bool(VCONFKEY_CISSAPPL_CALL_END_TONE_BOOL, &bstatus)) {
1693                                 CALL_ENG_DEBUG(ENG_ERR, "vconf_get_bool failed.\n");
1694                         }
1695
1696                         if (!bstatus) {
1697                                 CALL_ENG_DEBUG(ENG_DEBUG, "Disconnect Tone Settings not enabled \n");
1698                                 return FALSE;
1699                         }
1700
1701                         voicecall_snd_change_mm_path(papp_snd, VOICE_CALL_MM_ALERT_TONE);
1702
1703                         error_code = mm_sound_play_sound(VOICE_CALL_SND_DISCONNECT_SIGNAL_PATH, VOLUME_TYPE_CALL, __voicecall_snd_effect_cb, papp_snd, &papp_snd->mmfsoundplay_handle);
1704
1705                 }
1706                 break;
1707
1708         case VOICE_CALL_SND_EFFECT_CALL_MINUTE_MINDER:
1709                 {
1710                         voicecall_snd_change_mm_path(papp_snd, VOICE_CALL_MM_ALERT_TONE);
1711                         error_code = mm_sound_play_sound(VOICE_CALL_SND_MINUTE_MINDER_SIGNAL_PATH, VOLUME_TYPE_CALL, __voicecall_snd_effect_cb, papp_snd, &papp_snd->mmfsoundplay_handle);
1712                 }
1713                 break;
1714
1715         default:
1716                 CALL_ENG_DEBUG(ENG_DEBUG, "Invalid Effect Type: %d \n", effect_type);
1717
1718         }
1719
1720         if (MM_ERROR_NONE == error_code) {
1721                 papp_snd->effect_tone_status = VOICE_CALL_SND_STATUS_PLAY;
1722         }
1723
1724         CALL_ENG_DEBUG(ENG_DEBUG, "error code = [0x%x] \n", error_code);
1725         return (MM_ERROR_NONE == error_code) ? TRUE : FALSE;
1726 }
1727
1728 gboolean voicecall_snd_is_effect_playing(voicecall_snd_mgr_t *papp_snd)
1729 {
1730         CALL_ENG_DEBUG(ENG_ERR, "Effect tone status: %d\n", papp_snd->effect_tone_status);
1731         if (VOICE_CALL_SND_STATUS_PLAY == papp_snd->effect_tone_status) {
1732                 return TRUE;
1733         }
1734
1735         return FALSE;
1736 }
1737
1738 void voicecall_snd_stop_effect_tone(voicecall_snd_mgr_t *papp_snd)
1739 {
1740         CALL_ENG_DEBUG(ENG_ERR, "Effect tone status: %d\n", papp_snd->effect_tone_status);
1741
1742         if (VOICE_CALL_SND_STATUS_PLAY == papp_snd->effect_tone_status) {
1743                 if (MM_ERROR_NONE != mm_sound_stop_sound(papp_snd->mmfsoundplay_handle)) {
1744                         CALL_ENG_DEBUG(ENG_ERR, "MM Stop Sound Failed \n");
1745                 }
1746
1747                 papp_snd->effect_tone_status = VOICE_CALL_SND_STATUS_NONE;
1748                 papp_snd->mmfsoundplay_handle = VOICE_CALL_SND_INVALID_SND_HANDLE;
1749         }
1750         CALL_ENG_DEBUG(ENG_ERR, "Effect tone status: %d\n", papp_snd->effect_tone_status);
1751 }
1752
1753 void voicecall_snd_set_to_defaults(voicecall_snd_mgr_t *papp_snd)
1754 {
1755         call_vc_core_state_t *pcall_core = NULL;
1756
1757         CALL_ENG_DEBUG(ENG_DEBUG, "papp_snd = %p \n", papp_snd);
1758
1759         /*Backup core handle */
1760         pcall_core = (call_vc_core_state_t *)papp_snd->pcall_core;
1761
1762         /*Reset Sound Magr Data */
1763         memset(papp_snd, 0, sizeof(voicecall_snd_mgr_t));
1764
1765         /*Re Assign core handle */
1766         papp_snd->pcall_core = pcall_core;
1767
1768         /*Set to Defaults */
1769         papp_snd->pmm_player = VOICE_CALL_SND_INVALID_PLAYER_HANDLE;
1770         papp_snd->pmm_signal_player = VOICE_CALL_SND_INVALID_SND_HANDLE;
1771
1772         papp_snd->mmfsoundplay_handle = VOICE_CALL_SND_INVALID_SND_HANDLE;
1773         papp_snd->mmfalternateplay_handle = VOICE_CALL_SND_INVALID_SND_HANDLE;
1774
1775 }