RSA sync with private
[platform/core/messaging/msg-service.git] / msg_helper / MsgSoundPlayer.cpp
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 #include <pthread.h>
18
19 #include "MsgDebug.h"
20 #include "MsgCppTypes.h"
21 #include "MsgSettingTypes.h"
22 #include "MsgGconfWrapper.h"
23 #include "MsgUtilFile.h"
24 #include "MsgHelper.h"
25
26 #include <devman_managed.h>
27 #include <svi.h>
28
29 #include <mm_error.h>
30 #include <mm_player.h>
31 #include <mm_session_private.h>
32 #include <mm_sound.h>
33
34 extern void worker_done();
35
36 /*==================================================================================================
37                                      VARIABLES
38 ==================================================================================================*/
39 static MMHandleType hPlayerHandle = 0;
40 static bool bPlaying = false;
41 static bool bVibrating = false;
42 static int dev_handle;
43
44 pthread_mutex_t muMmPlay = PTHREAD_MUTEX_INITIALIZER;
45 pthread_cond_t cvMmPlay = PTHREAD_COND_INITIALIZER;
46
47 /*==================================================================================================
48                                      FUNCTION IMPLEMENTATION
49 ==================================================================================================*/
50
51 static gboolean MsgStopAndExit(void* data)
52 {
53         MsgSoundPlayStop();
54         if(!bPlaying && !bVibrating)
55                 worker_done();
56
57         return FALSE;
58 }
59
60 static gboolean MsgUninitAndExit(void* data)
61 {
62         MsgSoundPlayUninit();
63         if(!bPlaying && !bVibrating)
64                 worker_done();
65
66         return FALSE;
67 }
68
69 static gboolean MsgSoundMelodyTimeout(gpointer data)
70 {
71         MSG_BEGIN();
72
73         MsgSoundPlayStop();
74         if(!bPlaying && !bVibrating)
75                 worker_done();
76
77         MSG_END();
78
79         return FALSE;
80 }
81
82
83 static gboolean MsgSoundVibTimeout(gpointer data)
84 {
85         MSG_BEGIN();
86
87         int ret = 0;
88
89         if (bVibrating == true) {
90                 ret = device_haptic_stop_play(dev_handle);
91
92                 if (ret != 0) {
93                         MSG_DEBUG("Fail to stop haptic : [%d]", ret);
94                 }
95
96                 ret = device_haptic_close(dev_handle);
97
98                 if (ret != 0) {
99                         MSG_DEBUG("Fail to close haptic : [%d]", ret);
100                 }
101
102                 bVibrating = false;
103         }
104
105         if(!bPlaying && !bVibrating)
106                 worker_done();
107
108         MSG_END();
109
110         return FALSE;
111 }
112
113
114 static int MsgSoundPlayCallback(int message, void *param, void *user_param)
115 {
116         switch (message)
117         {
118                 case MM_MESSAGE_ERROR:
119                         MSG_DEBUG("ERROR is happened.");
120                         g_idle_add (MsgUninitAndExit, NULL);
121                         break;
122                 case MM_MESSAGE_BEGIN_OF_STREAM:
123                         MSG_DEBUG("Play is started.");
124                         break;
125                 case MM_MESSAGE_END_OF_STREAM:
126                 case MM_MESSAGE_STATE_INTERRUPTED:
127                         MSG_DEBUG("EOS or Interrupted.");
128                         g_idle_add (MsgStopAndExit, NULL);
129                         break;
130                 default:
131                         MSG_DEBUG("message = %d", message);
132                         break;
133         }
134
135         return 1;
136 }
137
138
139 void* MsgPlayThread(void *data)
140 {
141         MSG_BEGIN();
142
143         bool bSoundOn = false;
144         bool bVibrationOn = false;
145         int callStatus = 0;
146         /* 0 - off, 1 - sound, 2 - vibration */
147         int alertOnCall = 0;
148
149         bool isEmergency = false;
150
151         if (data)
152                 isEmergency = (bool)data;
153
154         char *msg_tone_file_path = NULL;
155         AutoPtr<char> buf(&msg_tone_file_path);
156
157         msg_tone_file_path = new char[MAX_SOUND_FILE_LEN];
158
159         if (isEmergency) {
160         } else {
161                 char *tmpFileFath = NULL;
162
163                 tmpFileFath = MsgSettingGetString(VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR);
164
165                 if (tmpFileFath == NULL || MsgGetFileSize(tmpFileFath) < 1) {
166                         strncpy(msg_tone_file_path, DEFAULT_FILE, MAX_SOUND_FILE_LEN-1);
167                 } else {
168                         strncpy(msg_tone_file_path, tmpFileFath, MAX_SOUND_FILE_LEN-1);
169                         free(tmpFileFath);
170                         tmpFileFath = NULL;
171                 }
172         }
173
174         MSG_DEBUG("Emergency=[%d], Sound File [%s]", isEmergency, msg_tone_file_path);
175
176         MsgSettingGetBool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &bSoundOn);
177         MsgSettingGetBool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &bVibrationOn);
178
179         int err = MM_ERROR_NONE;
180
181         if (isEmergency)
182                 err = mm_session_init(MM_SESSION_TYPE_EMERGENCY);
183         else
184                 err = mm_session_init(MM_SESSION_TYPE_NOTIFY);
185
186         if(err != MM_ERROR_NONE)
187                 MSG_DEBUG("MM Session Init Failed");
188         else
189                 MSG_DEBUG("MM Session Init Success : %d", err);
190
191         hPlayerHandle = 0;
192
193         err = mm_player_create(&hPlayerHandle);
194
195         if (err != MM_ERROR_NONE) {
196                 MSG_DEBUG("creating the player handle failed");
197                 return NULL;
198         }
199
200         /* Setting the call back function msg_callback */
201         mm_player_set_message_callback(hPlayerHandle, MsgSoundPlayCallback, (void *)hPlayerHandle);
202
203         callStatus = MsgSettingGetInt(VCONFKEY_CALL_STATE);
204         MSG_DEBUG("Call Status = %d", callStatus);
205
206         if (callStatus > VCONFKEY_CALL_OFF && callStatus < VCONFKEY_CALL_STATE_MAX) {
207                 alertOnCall = MsgSettingGetInt(VCONFKEY_CISSAPPL_ALERT_ON_CALL_INT);
208                 MSG_DEBUG("Alert On Call = %d", alertOnCall);
209
210                 if (alertOnCall == 0) {
211                         MSG_DEBUG("Call is active & Alert on Call - Off");
212                 } else if (alertOnCall == 1) {
213                         MSG_DEBUG("Call is active & Alert on Call - Sound");
214
215                         if (bSoundOn)
216                                 MsgSoundPlayDtmf();
217                 } else if (alertOnCall == 2) {
218                         MSG_DEBUG("Call is active & Alert on Call - Vibration");
219
220                         if (bVibrationOn)
221                                 MsgSoundPlayVibration();
222                 }
223         } else{
224                 MSG_DEBUG("Call is not active");
225
226                 if (bVibrationOn) {
227                         MSG_DEBUG("Play vibration.");
228                         MsgSoundPlayVibration();
229                 }
230
231                 if (bSoundOn) {
232                         MSG_DEBUG("Play sound.");
233                         MsgSoundPlayMelody(msg_tone_file_path, false);
234                 }
235         }
236
237         err = mm_session_finish();
238
239         if (err != MM_ERROR_NONE)
240                 MSG_DEBUG("MM Session Finish Failed");
241         else
242                 MSG_DEBUG("MM Session Finish Success : %d", err);
243
244         if(!bPlaying && !bVibrating)
245                 worker_done();
246
247         MSG_END();
248
249         return NULL;
250 }
251
252
253 msg_error_t MsgSoundPlayUninit()
254 {
255         MSG_BEGIN();
256
257         int err = MM_ERROR_NONE;
258
259         /* Uninitializing the player module */
260         err = mm_player_unrealize(hPlayerHandle);
261
262         /* Destroying the player handle */
263         err = mm_player_destroy(hPlayerHandle);
264
265         pthread_mutex_lock(&muMmPlay);
266
267         bPlaying = false;
268
269         pthread_mutex_unlock(&muMmPlay);
270
271         pthread_cond_signal(&cvMmPlay);
272
273         hPlayerHandle = 0;
274
275         MSG_END();
276
277         return MSG_SUCCESS;
278 }
279
280
281 void MsgSoundPlayStart(bool isEmergency)
282 {
283         MSG_BEGIN();
284
285         pthread_mutex_lock(&muMmPlay);
286
287         if (bPlaying == true) {
288                 MSG_DEBUG("Ringtone is Playing...");
289                 pthread_mutex_unlock(&muMmPlay);
290                 return;
291         }
292
293         pthread_mutex_unlock(&muMmPlay);
294
295         pthread_t tid;
296
297         if (pthread_create(&tid, NULL, &MsgPlayThread, (void*)isEmergency) == 0) {
298                 MSG_DEBUG("Ring alert thread created = %d", tid);
299         } else {
300                 MSG_DEBUG("Creating Thread was failed");
301                 return;
302         }
303
304         MSG_END();
305 }
306
307
308 void MsgSoundPlayStop()
309 {
310         MSG_BEGIN();
311
312         pthread_mutex_lock(&muMmPlay);
313
314         if (bPlaying == false) {
315                 MSG_DEBUG("Ringtone is Not Playing...");
316                 pthread_mutex_unlock(&muMmPlay);
317                 return;
318         }
319
320         pthread_mutex_unlock(&muMmPlay);
321
322         /* Stop playing media contents */
323         MSG_DEBUG("Before mm_player_stop, %p", hPlayerHandle);
324
325         int err = mm_player_stop(hPlayerHandle);
326
327         MSG_DEBUG("After mm_player_stop");
328
329         if (err != MM_ERROR_NONE) {
330                 MSG_DEBUG("stopping the player handle failed");
331         }
332
333         MsgSoundPlayUninit();
334
335         MSG_END();
336 }
337
338
339 int MsgSoundPlayMelody(char *pMsgToneFilePath, bool bIncreasing)
340 {
341         int err = MM_ERROR_NONE;
342
343         /* Setting fade in,out */
344         err = mm_player_set_attribute(hPlayerHandle, NULL, "sound_priority", 2, NULL);
345
346         if (err != MM_ERROR_NONE) {
347                 MSG_DEBUG("error setting the profile attr");
348                 return err;
349         }
350
351         /* Setting the Volume */
352         err = mm_player_set_attribute(hPlayerHandle, NULL, "sound_volume_type", MM_SOUND_VOLUME_TYPE_NOTIFICATION,
353                                                                                                         "profile_uri", pMsgToneFilePath, strlen(pMsgToneFilePath), NULL);
354
355         if (err != MM_ERROR_NONE) {
356                 MSG_DEBUG("error setting the profile attr");
357                 return err;
358         }
359
360         err = mm_player_realize(hPlayerHandle);
361
362         if (err != MM_ERROR_NONE) {
363                 MSG_DEBUG("mm_player_realize() error : [%d]", err);
364                 return err;
365         }
366
367         /* Add Timer to stop playing after 5 sec. */
368         int g_contact_timer = -1;
369         g_contact_timer = g_timeout_add(5500, (GSourceFunc)MsgSoundMelodyTimeout, NULL);
370
371         err = mm_player_start(hPlayerHandle);
372
373         if (err != MM_ERROR_NONE) {
374                 MSG_DEBUG("mm_player_start, FAIL [%x]", err);
375                 bPlaying = false;
376
377                 return err;
378         }
379
380         bPlaying = true;
381
382         pthread_mutex_lock(&muMmPlay);
383
384         while (bPlaying)
385         {
386                 MSG_DEBUG("Ring Alert Playing");
387                 pthread_cond_wait(&cvMmPlay, &muMmPlay);
388         }
389
390         pthread_mutex_unlock(&muMmPlay);
391
392         MSG_DEBUG("Ring Alert Idle");
393
394         return err;
395 }
396
397
398 void MsgSoundPlayVibration()
399 {
400         MSG_BEGIN();
401
402         int ret = 0;
403         int vibLevel = 0;
404         char ivtFilePath[MAX_SOUND_FILE_LEN] = {0,};
405
406         vibLevel = MsgSettingGetInt(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT);
407
408         if (vibLevel > 0) {
409                 bVibrating = true;
410
411                 dev_handle = device_haptic_open(DEV_IDX_0, 0);
412
413                 g_timeout_add(MSG_VIBRATION_INTERVAL , MsgSoundVibTimeout, NULL);
414
415                 /* set timer to stop vibration, then play melody */
416                 svi_get_path(SVI_TYPE_VIB, SVI_VIB_NOTIFICATION_MESSAGE, ivtFilePath, sizeof(ivtFilePath));
417                 ret = device_haptic_play_file(dev_handle, ivtFilePath, HAPTIC_TEST_ITERATION, vibLevel);
418
419                 if (ret != 0) {
420                         MSG_DEBUG("Fail to play haptic : [%d]", ret);
421                 }
422         }
423
424         MSG_END();
425 }
426
427 void MsgSoundPlayDtmf()
428 {
429         MSG_BEGIN();
430
431         int ret = 0;
432         int hToneHandle = 0;
433
434         ret = mm_sound_play_tone(MM_SOUND_TONE_PROP_BEEP2, VOLUME_TYPE_SYSTEM, 1.0, 300, &hToneHandle);
435
436         if(ret < 0) {
437                 MSG_DEBUG("play tone failed\n");
438         } else {
439                 MSG_DEBUG("play tone success\n");
440         }
441
442         MSG_END();
443 }
444
445
446 int MsgSoundGetUnreadMsgCnt()
447 {
448         int unreadCnt = 0;
449
450         /*  Get SMS Count */
451         unreadCnt = MsgSettingGetInt(VCONFKEY_MESSAGE_RECV_SMS_STATE);
452
453         /*  Get MMS Count */
454         unreadCnt += MsgSettingGetInt(VCONFKEY_MESSAGE_RECV_MMS_STATE);
455
456         MSG_DEBUG("unread count : [%d]", unreadCnt);
457
458         return unreadCnt;
459 }