update tizen source
[framework/messaging/msg-service.git] / msg_helper / MsgSoundPlayer.cpp
1 /*
2 *
3 * Copyright (c) 2000-2012 Samsung Electronics Co., Ltd. All Rights Reserved.
4 *
5 * This file is part of msg-service.
6 *
7 * Contact: Jaeyun Jeong <jyjeong@samsung.com>
8 *          Sangkoo Kim <sangkoo.kim@samsung.com>
9 *          Seunghwan Lee <sh.cat.lee@samsung.com>
10 *          SoonMin Jung <sm0415.jung@samsung.com>
11 *          Jae-Young Lee <jy4710.lee@samsung.com>
12 *          KeeBum Kim <keebum.kim@samsung.com>
13 *
14 * PROPRIETARY/CONFIDENTIAL
15 *
16 * This software is the confidential and proprietary information of
17 * SAMSUNG ELECTRONICS ("Confidential Information"). You shall not
18 * disclose such Confidential Information and shall use it only in
19 * accordance with the terms of the license agreement you entered
20 * into with SAMSUNG ELECTRONICS.
21 *
22 * SAMSUNG make no representations or warranties about the suitability
23 * of the software, either express or implied, including but not limited
24 * to the implied warranties of merchantability, fitness for a particular
25 * purpose, or non-infringement. SAMSUNG shall not be liable for any
26 * damages suffered by licensee as a result of using, modifying or
27 * distributing this software or its derivatives.
28 *
29 */
30
31 #include <pthread.h>
32
33 #include "MsgDebug.h"
34 #include "MsgCppTypes.h"
35 #include "MsgSettingTypes.h"
36 #include "MsgGconfWrapper.h"
37 #include "MsgHelper.h"
38
39 #include <devman_haptic.h>
40 #include <svi.h>
41
42 #include <mm_error.h>
43 #include <mm_player.h>
44 #include <mm_session_private.h>
45
46
47 extern void worker_done();
48
49 /*==================================================================================================
50                                      VARIABLES
51 ==================================================================================================*/
52 static MMHandleType hPlayerHandle = 0;
53 static bool bPlaying = false;
54 static bool bVibrating = false;
55 static int dev_handle;
56
57 pthread_mutex_t muMmPlay = PTHREAD_MUTEX_INITIALIZER;
58 pthread_cond_t cvMmPlay = PTHREAD_COND_INITIALIZER;
59
60 /*==================================================================================================
61                                      FUNCTION IMPLEMENTATION
62 ==================================================================================================*/
63 static gboolean MsgSoundMelodyTimeout(gpointer data)
64 {
65         MSG_BEGIN();
66
67         MsgSoundPlayStop();
68         if(!bPlaying && !bVibrating)
69                 worker_done();
70
71         MSG_END();
72
73         return FALSE;
74 }
75
76
77 static gboolean MsgSoundVibTimeout(gpointer data)
78 {
79         MSG_BEGIN();
80
81         int ret = 0;
82
83         if (bVibrating == true) {
84                 ret = device_haptic_stop_play(dev_handle);
85
86                 if (ret != 0) {
87                         MSG_DEBUG("Fail to stop haptic : [%d]", ret);
88                 }
89
90                 ret = device_haptic_close(dev_handle);
91
92                 if (ret != 0) {
93                         MSG_DEBUG("Fail to close haptic : [%d]", ret);
94                 }
95
96                 bVibrating = false;
97         }
98
99         if(!bPlaying && !bVibrating)
100                 worker_done();
101
102         MSG_END();
103
104         return FALSE;
105 }
106
107
108 static int MsgSoundPlayCallback(int message, void *param, void *user_param)
109 {
110         switch (message)
111         {
112                 case MM_MESSAGE_ERROR:
113                         MSG_DEBUG("ERROR is happened.");
114                         MsgSoundPlayUninit();
115                         break;
116                 case MM_MESSAGE_BEGIN_OF_STREAM:
117                         MSG_DEBUG("Play is started.");
118                         break;
119                 case MM_MESSAGE_END_OF_STREAM:
120                         MSG_DEBUG("end of stream");
121                         MsgSoundPlayStop();
122                         if(!bPlaying && !bVibrating)
123                                 worker_done();
124                         break;
125                 default:
126                         MSG_DEBUG("message = %d", message);
127                         break;
128         }
129
130         return 1;
131 }
132
133
134 void* MsgPlayThread(void *data)
135 {
136         MSG_BEGIN();
137
138         bool bSoundOn = false;
139         bool bVibrationOn = false;
140         int callStatus = 0;     /* 0 - off, 1 - sound, 2 - vibration */
141         int alertOnCall = 0;
142
143         char *msg_tone_file_path = NULL;
144         AutoPtr<char> buf(&msg_tone_file_path);
145
146         char *tmpFileFath = NULL;
147
148         tmpFileFath = MsgSettingGetString(VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR);
149
150         if (tmpFileFath == NULL) {
151                 msg_tone_file_path = new char[MAX_SOUND_FILE_LEN];
152                 strncpy(msg_tone_file_path, DEFAULT_FILE, MAX_SOUND_FILE_LEN-1);
153         } else {
154                 msg_tone_file_path = new char[MAX_SOUND_FILE_LEN];
155                 strncpy(msg_tone_file_path, tmpFileFath, MAX_SOUND_FILE_LEN-1);
156                 free(tmpFileFath);
157                 tmpFileFath = NULL;
158         }
159
160         MSG_DEBUG("Sound File [%s]", msg_tone_file_path);
161
162         MsgSettingGetBool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &bSoundOn);
163         MsgSettingGetBool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &bVibrationOn);
164
165         int err = MM_ERROR_NONE;
166
167         err = mm_session_init(MM_SESSION_TYPE_NOTIFY);
168
169         if(err != MM_ERROR_NONE)
170                 MSG_DEBUG("MM Session Init Failed");
171         else
172                 MSG_DEBUG("MM Session Init Success : %d", err);
173
174         hPlayerHandle = 0;
175
176         err = mm_player_create(&hPlayerHandle);
177
178         if (err != MM_ERROR_NONE) {
179                 MSG_DEBUG("creating the player handle failed");
180                 return NULL;
181         }
182
183         /* Setting the call back function msg_callback */
184         mm_player_set_message_callback(hPlayerHandle, MsgSoundPlayCallback, (void *)hPlayerHandle);
185
186         callStatus = MsgSettingGetInt(VCONFKEY_CALL_STATE);
187         MSG_DEBUG("Call Status = %d", callStatus);
188
189         if (callStatus > VCONFKEY_CALL_OFF && callStatus < VCONFKEY_CALL_STATE_MAX) {
190                 alertOnCall = MsgSettingGetInt(VCONFKEY_CISSAPPL_ALERT_ON_CALL_INT);
191                 MSG_DEBUG("Alert On Call = %d", alertOnCall);
192
193                 if (alertOnCall == 0) {
194                         MSG_DEBUG("Call is active & Alert on Call - Off");
195                 } else if (alertOnCall == 1) {
196                         MSG_DEBUG("Call is active & Alert on Call - Sound");
197
198                         if (bSoundOn)
199                                 MsgSoundPlayMelody(msg_tone_file_path, false);
200                 } else if (alertOnCall == 2) {
201                         MSG_DEBUG("Call is active & Alert on Call - Vibration");
202
203                         if (bVibrationOn)
204                                 MsgSoundPlayVibration();
205                 }
206         } else{
207                 MSG_DEBUG("Call is not active");
208
209                 if (bVibrationOn) {
210                         MSG_DEBUG("Play vibration.");
211                         MsgSoundPlayVibration();
212                 }
213
214                 if (bSoundOn) {
215                         MSG_DEBUG("Play sound.");
216                         MsgSoundPlayMelody(msg_tone_file_path, false);
217                 }
218         }
219
220         err = mm_session_finish();
221
222         if (err != MM_ERROR_NONE)
223                 MSG_DEBUG("MM Session Finish Failed");
224         else
225                 MSG_DEBUG("MM Session Finish Success : %d", err);
226
227         if(!bPlaying && !bVibrating)
228                 worker_done();
229
230         MSG_END();
231
232         return NULL;
233 }
234
235
236 MSG_ERROR_T MsgSoundPlayUninit()
237 {
238         MSG_BEGIN();
239
240         int err = MM_ERROR_NONE;
241
242         /* Uninitializing the player module */
243         err = mm_player_unrealize(hPlayerHandle);
244
245         /* Destroying the player handle */
246         err = mm_player_destroy(hPlayerHandle);
247
248         pthread_mutex_lock(&muMmPlay);
249
250         bPlaying = false;
251
252         pthread_mutex_unlock(&muMmPlay);
253
254         pthread_cond_signal(&cvMmPlay);
255
256         hPlayerHandle = 0;
257
258         MSG_END();
259
260         return MSG_SUCCESS;
261 }
262
263
264 void MsgSoundPlayStart()
265 {
266         MSG_BEGIN();
267
268         pthread_mutex_lock(&muMmPlay);
269
270         if (bPlaying == true) {
271                 MSG_DEBUG("Ringtone is Playing...");
272                 pthread_mutex_unlock(&muMmPlay);
273                 return;
274         }
275
276         pthread_mutex_unlock(&muMmPlay);
277
278         pthread_t tid;
279
280         if (pthread_create(&tid, NULL, &MsgPlayThread, (void*)NULL) == 0) {
281                 MSG_DEBUG("Ring alert thread created = %d", tid);
282         } else {
283                 MSG_DEBUG("Creating Thread was failed");
284                 return;
285         }
286
287         MSG_END();
288 }
289
290
291 void MsgSoundPlayStop()
292 {
293         MSG_BEGIN();
294
295         pthread_mutex_lock(&muMmPlay);
296
297         if (bPlaying == false) {
298                 MSG_DEBUG("Ringtone is Not Playing...");
299                 pthread_mutex_unlock(&muMmPlay);
300                 return;
301         }
302
303         pthread_mutex_unlock(&muMmPlay);
304
305         /* Stop playing media contents */
306         MSG_DEBUG("Before mm_player_stop, %p", hPlayerHandle);
307
308         int err = mm_player_stop(hPlayerHandle);
309
310         MSG_DEBUG("After mm_player_stop");
311
312         if (err != MM_ERROR_NONE) {
313                 MSG_DEBUG("stopping the player handle failed");
314         }
315
316         MsgSoundPlayUninit();
317
318         MSG_END();
319 }
320
321
322 int MsgSoundPlayMelody(char *pMsgToneFilePath, bool bIncreasing)
323 {
324         int err = MM_ERROR_NONE;
325
326         /* Setting fade in,out */
327         err = mm_player_set_attribute(hPlayerHandle, NULL, "sound_priority", 2, NULL);
328
329         if (err != MM_ERROR_NONE) {
330                 MSG_DEBUG("error setting the profile attr");
331                 return err;
332         }
333
334         /* Setting the Volume */
335         err = mm_player_set_attribute(hPlayerHandle, NULL, "sound_volume_type", MM_SOUND_VOLUME_TYPE_NOTIFICATION,
336                                                                                                         "profile_uri", pMsgToneFilePath, strlen(pMsgToneFilePath), NULL);
337
338         if (err != MM_ERROR_NONE) {
339                 MSG_DEBUG("error setting the profile attr");
340                 return err;
341         }
342
343         err = mm_player_realize(hPlayerHandle);
344
345         if (err != MM_ERROR_NONE) {
346                 MSG_DEBUG("mm_player_realize() error : [%d]", err);
347                 return err;
348         }
349
350         /* Add Timer to stop playing after 5 sec. */
351         int g_contact_timer = -1;
352         g_contact_timer = g_timeout_add(5500, (GSourceFunc)MsgSoundMelodyTimeout, NULL);
353
354         err = mm_player_start(hPlayerHandle);
355
356         if (err != MM_ERROR_NONE) {
357                 MSG_DEBUG("mm_player_start, FAIL [%x]", err);
358                 bPlaying = false;
359
360                 return err;
361         }
362
363         bPlaying = true;
364
365         pthread_mutex_lock(&muMmPlay);
366
367         while (bPlaying)
368         {
369                 MSG_DEBUG("Ring Alert Playing");
370                 pthread_cond_wait(&cvMmPlay, &muMmPlay);
371         }
372
373         pthread_mutex_unlock(&muMmPlay);
374
375         MSG_DEBUG("Ring Alert Idle");
376
377         return err;
378 }
379
380
381 void MsgSoundPlayVibration()
382 {
383         MSG_BEGIN();
384
385         int ret = 0;
386         int vibLevel = 0;
387         char ivtFilePath[MAX_SOUND_FILE_LEN] = {0,};
388
389         vibLevel = MsgSettingGetInt(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT);
390
391         if (vibLevel > 0) {
392                 bVibrating = true;
393
394                 dev_handle = device_haptic_open(DEV_IDX_0, 0);
395
396                 g_timeout_add(MSG_VIBRATION_INTERVAL , MsgSoundVibTimeout, NULL);
397
398                 /* set timer to stop vibration, then play melody */
399                 svi_get_path(SVI_TYPE_VIB, SVI_VIB_NOTIFICATION_MESSAGE, ivtFilePath, sizeof(ivtFilePath));
400                 ret = device_haptic_play_file(dev_handle, ivtFilePath, HAPTIC_TEST_ITERATION, vibLevel);
401
402                 if (ret != 0) {
403                         MSG_DEBUG("Fail to play haptic : [%d]", ret);
404                 }
405         }
406
407         MSG_END();
408 }
409
410
411 int MsgSoundGetUnreadMsgCnt()
412 {
413         int unreadCnt = 0;
414
415         /*  Get SMS Count */
416         unreadCnt = MsgSettingGetInt(VCONFKEY_MESSAGE_RECV_SMS_STATE);
417
418         /*  Get MMS Count */
419         unreadCnt += MsgSettingGetInt(VCONFKEY_MESSAGE_RECV_MMS_STATE);
420
421         MSG_DEBUG("unread count : [%d]", unreadCnt);
422
423         return unreadCnt;
424 }